From 84a746468a3f7e5b39a3ed53090a19a8dec8cb10 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期一, 06 九月 2021 11:48:25 +0800
Subject: [PATCH] 2021-09-06

---
 src/components/normalform/modalform/index.scss     |    2 
 src/menu/components/tree/antd-tree/options.jsx     |  125 ++++++++++
 src/menu/components/table/normal-table/options.jsx |  175 ++++++++++++++
 src/mob/components/tabs/antv-tabs/index.jsx        |   17 +
 src/mob/components/tabs/antv-tabs/options.jsx      |   96 +++++++
 src/menu/components/tabs/antv-tabs/options.jsx     |   96 +++++++
 src/menu/components/search/main-search/index.jsx   |   17 +
 src/views/rolemanage/index.jsx                     |    4 
 /dev/null                                          |   15 -
 src/menu/components/tree/antd-tree/index.jsx       |   17 +
 src/menu/components/table/normal-table/index.jsx   |   17 +
 src/menu/components/search/main-search/options.jsx |   84 +++++++
 src/menu/components/tabs/antv-tabs/index.jsx       |   17 +
 13 files changed, 649 insertions(+), 33 deletions(-)

diff --git a/src/components/normalform/modalform/index.scss b/src/components/normalform/modalform/index.scss
index 23b5f23..594563d 100644
--- a/src/components/normalform/modalform/index.scss
+++ b/src/components/normalform/modalform/index.scss
@@ -48,7 +48,7 @@
     margin-top: 7px;
     overflow: hidden;
     .color-sketch-block-box {
-      min-width: 100px;
+      min-width: 50px;
       .color-sketch-block-inner {
         box-shadow: 0 0 0 1px rgba(0, 0, 0, .1) inset;
       }
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 91421d3..92fce35 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -12,12 +12,13 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import DragElement from './dragsearch'
+import getWrapForm from './options'
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 const { confirm } = Modal
 
-const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const FieldsComponent = asyncIconComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
 const SearchForm = asyncIconComponent(() => import('@/templates/sharecomponent/searchcomponent/searchform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
@@ -370,6 +371,16 @@
     })
   }
 
+  getWrapForms = () => {
+    const { wrap, action } = this.state.card
+
+    return getWrapForm(wrap, action)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -396,7 +407,9 @@
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <Icon className="plus" title="娣诲姞" onClick={this.addSearch} type="plus" />
-            <WrapComponent config={card} updateConfig={this.updateComponent}/>
+            <NormalForm title="鎼滅储璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="mainsearch" card={card}/>
             <PasteComponent config={card} options={['search', 'form']} updateConfig={this.checkComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
diff --git a/src/menu/components/search/main-search/options.jsx b/src/menu/components/search/main-search/options.jsx
new file mode 100644
index 0000000..996e994
--- /dev/null
+++ b/src/menu/components/search/main-search/options.jsx
@@ -0,0 +1,84 @@
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (wrap, action = []) {
+  let roleList = sessionStorage.getItem('sysRoles')
+  let appType = sessionStorage.getItem('appType')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch (e) {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const wrapForm = [
+    {
+      type: 'text',
+      field: 'name',
+      label: '缁勪欢鍚嶇О',
+      initval: wrap.name || '',
+      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: wrap.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'advanceWidth',
+      label: '楂樼骇鎼滅储',
+      initval: wrap.advanceWidth || 1000,
+      tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
+      min: 10,
+      max: 3000,
+      precision: 0,
+      required: false
+    },
+    {
+      type: 'radio',
+      field: 'float',
+      label: '瀵归綈',
+      initval: wrap.float || 'left',
+      tooltip: '鍙冲榻愭椂锛岄殣钘忔悳绱㈡寜閽��',
+      required: false,
+      options: [
+        {value: 'left', label: '宸﹀榻�'},
+        {value: 'right', label: '鍙冲榻�'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'show',
+      label: '鎼滅储鎸夐挳',
+      initval: wrap.show || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: wrap.blacklist || [],
+      required: false,
+      options: roleList,
+      forbid: !!appType
+    },
+  ]
+
+  return wrapForm
+} 
\ No newline at end of file
diff --git a/src/menu/components/search/main-search/wrapsetting/index.jsx b/src/menu/components/search/main-search/wrapsetting/index.jsx
deleted file mode 100644
index d8bbaa6..0000000
--- a/src/menu/components/search/main-search/wrapsetting/index.jsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Icon, Modal } from 'antd'
-
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import SettingForm from './settingform'
-import './index.scss'
-
-class DataSource extends Component {
-  static propTpyes = {
-    config: PropTypes.any,
-    updateConfig: PropTypes.func
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    visible: false,
-    wrap: null
-  }
-
-  UNSAFE_componentWillMount () {
-    const { config } = this.props
-
-    this.setState({wrap: fromJS(config.wrap).toJS()})
-  }
-
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
-  }
-
-  editDataSource = () => {
-    this.setState({
-      visible: true
-    })
-  }
-
-  verifySubmit = () => {
-    const { config } = this.props
-
-    this.verifyRef.handleConfirm().then(res => {
-
-      this.setState({
-        wrap: res,
-        visible: false
-      })
-      this.props.updateConfig({...config, wrap: res})
-    })
-  }
-
-  render () {
-    const { visible, dict, wrap } = this.state
-
-    return (
-      <div className="model-menu-setting-wrap">
-        <Icon type="edit" onClick={() => this.editDataSource()} />
-        <Modal
-          wrapClassName="popview-modal"
-          title={'鎼滅储璁剧疆'}
-          visible={visible}
-          width={700}
-          maskClosable={false}
-          okText={dict['model.submit']}
-          onOk={this.verifySubmit}
-          onCancel={() => { this.setState({ visible: false }) }}
-          destroyOnClose
-        >
-          <SettingForm
-            dict={dict}
-            wrap={wrap}
-            inputSubmit={this.verifySubmit}
-            wrappedComponentRef={(inst) => this.verifyRef = inst}
-          />
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default DataSource
\ No newline at end of file
diff --git a/src/menu/components/search/main-search/wrapsetting/index.scss b/src/menu/components/search/main-search/wrapsetting/index.scss
deleted file mode 100644
index 04372e6..0000000
--- a/src/menu/components/search/main-search/wrapsetting/index.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.model-menu-setting-wrap {
-  display: inline-block;
-
-  >.anticon-edit {
-    color: #1890ff;
-  }
-}
\ No newline at end of file
diff --git a/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx b/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx
deleted file mode 100644
index 7e8715c..0000000
--- a/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx
+++ /dev/null
@@ -1,176 +0,0 @@
-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,      // 瀛楀吀椤�
-    wrap: PropTypes.object,      // 鏁版嵁婧愰厤缃�
-    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
-  }
-
-  state = {
-    roleList: [],
-    appType: sessionStorage.getItem('appType')
-  }
-
-  UNSAFE_componentWillMount () {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch (e) {
-        roleList = []
-      }
-    } else {
-      roleList = []
-    }
-
-    this.setState({roleList})
-  }
-
-  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 { wrap } = this.props
-    const { getFieldDecorator } = this.props.form
-    const { roleList, appType } = this.state
-
-    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('name', {
-                  initialValue: wrap.name,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!'
-                    }
-                  ]
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit}/>)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
-                  <Icon type="question-circle" />
-                  瀹藉害
-                </Tooltip>
-              }>
-                {getFieldDecorator('width', {
-                  initialValue: wrap.width || 24,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '瀹藉害!'
-                    }
-                  ]
-                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit}/>)}
-              </Form.Item>
-            </Col>
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��">
-                  <Icon type="question-circle" />
-                  楂樼骇鎼滅储
-                </Tooltip>
-              }>
-                {getFieldDecorator('advanceWidth', {
-                  initialValue: wrap.advanceWidth || 1000
-                })(<InputNumber min={10} max={3000} precision={0}/>)}
-              </Form.Item>
-            </Col> : null}
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鍙冲榻愭椂锛岄殣钘忔悳绱㈡寜閽��">
-                  <Icon type="question-circle" />
-                  瀵归綈
-                </Tooltip>
-              }>
-                {getFieldDecorator('float', {
-                  initialValue: wrap.float || 'left'
-                })(
-                  <Radio.Group>
-                    <Radio value="left">宸﹀榻�</Radio>
-                    <Radio value="right">鍙冲榻�</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <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>
-            <Col span={12}>
-              <Form.Item label="榛戝悕鍗�">
-                {getFieldDecorator('blacklist', {
-                  initialValue: wrap.blacklist || []
-                })(
-                  <Select
-                    showSearch
-                    mode="multiple"
-                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  >
-                    {roleList.map(option =>
-                      <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-          </Row>
-        </Form>
-      </div>
-    )
-  }
-}
-
-export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/search/main-search/wrapsetting/settingform/index.scss b/src/menu/components/search/main-search/wrapsetting/settingform/index.scss
deleted file mode 100644
index 159130b..0000000
--- a/src/menu/components/search/main-search/wrapsetting/settingform/index.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.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
index fe7b530..2c1524d 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -7,6 +7,7 @@
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
+import getWrapForm from './options'
 import Utils from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
@@ -14,6 +15,7 @@
 import './index.scss'
 
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const SearchComponent = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent'))
 const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -22,7 +24,6 @@
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const ColumnComponent = asyncComponent(() => import('./columns'))
-const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
 
 class TableCardEditComponent extends Component {
   static propTpyes = {
@@ -375,6 +376,16 @@
     }
   }
 
+  getWrapForms = () => {
+    const { wrap, action } = this.state.card
+
+    return getWrapForm(wrap, action)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -394,7 +405,9 @@
             <Icon className="plus" title="娣诲姞鍒�" onClick={this.addColumns} type="plus" />
             {appType !== 'mob' ? <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" /> : null}
             <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" />
-            <WrapComponent config={card} updateConfig={this.updateComponent} />
+            <NormalForm title="琛ㄦ牸璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="normaltable" card={card}/>
             <PasteComponent config={card} options={['action', 'search', 'form', 'cols']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
diff --git a/src/menu/components/table/normal-table/options.jsx b/src/menu/components/table/normal-table/options.jsx
new file mode 100644
index 0000000..4946bdf
--- /dev/null
+++ b/src/menu/components/table/normal-table/options.jsx
@@ -0,0 +1,175 @@
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (wrap, action = []) {
+  let roleList = sessionStorage.getItem('sysRoles')
+  let appType = sessionStorage.getItem('appType')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch (e) {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const wrapForm = [
+    {
+      type: 'text',
+      field: 'title',
+      label: '鏍囬',
+      initval: wrap.title || '',
+      required: false
+    },
+    {
+      type: 'text',
+      field: 'name',
+      label: '缁勪欢鍚嶇О',
+      initval: wrap.name || '',
+      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
+      required: true
+    },
+    {
+      type: 'radio',
+      field: 'tableType',
+      label: '琛ㄦ牸灞炴��',
+      initval: wrap.tableType,
+      required: false,
+      options: [
+        {value: '', label: '涓嶅彲閫�'},
+        {value: 'radio', label: '鍗曢��'},
+        {value: 'checkbox', label: '澶氶��'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'bordered',
+      label: '杈规',
+      initval: wrap.bordered || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏈�'},
+        {value: 'false', label: '鏃�'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'tableHeader',
+      label: '琛ㄥご',
+      initval: wrap.tableHeader || 'show',
+      required: false,
+      options: [
+        {value: 'show', label: '鏄剧ず'},
+        {value: 'hidden', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'collapse',
+      label: '鍙敹璧�',
+      initval: wrap.collapse || 'false',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'size',
+      label: '琛ㄦ牸澶у皬',
+      initval: wrap.size || 'middle',
+      required: false,
+      options: [
+        {value: 'default', label: '澶�'},
+        {value: 'middle', label: '涓�'},
+        {value: 'small', label: '灏�'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'mode',
+      label: '妯″紡',
+      initval: wrap.mode || 'default',
+      required: false,
+      options: [
+        {value: 'default', label: '甯歌'},
+        {value: 'ghost', label: '閫忔槑'},
+      ]
+    },
+    {
+      type: 'color',
+      field: 'borderColor',
+      label: '杈规棰滆壊',
+      initval: wrap.borderColor || '#e8e8e8',
+      tooltip: '榛樿鍊� #e8e8e8銆�',
+      required: false
+    },
+    {
+      type: 'color',
+      field: 'color',
+      label: '瀛椾綋棰滆壊',
+      initval: wrap.color || 'rgba(0, 0, 0, 0.65)',
+      tooltip: '榛樿鍊� rgba(0, 0, 0, 0.65)銆�',
+      required: false
+    },
+    {
+      type: 'number',
+      field: 'fontSize',
+      label: '瀛椾綋澶у皬',
+      initval: wrap.fontSize || 24,
+      min: 12,
+      max: 30,
+      precision: 0,
+      required: false
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: wrap.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'advanceWidth',
+      label: '楂樼骇鎼滅储',
+      initval: wrap.advanceWidth || 1000,
+      tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
+      min: 10,
+      max: 3000,
+      precision: 0,
+      required: false,
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'select',
+      field: 'doubleClick',
+      label: '鍙屽嚮浜嬩欢',
+      initval: wrap.doubleClick || '',
+      tooltip: '鍙屽嚮琛ㄦ牸涓锛岃Е鍙戠殑鎸夐挳銆�',
+      required: false,
+      allowClear: true,
+      options: action.map(item => ({value: item.uuid, label: item.label})),
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: wrap.blacklist || [],
+      required: false,
+      options: roleList,
+      forbid: !!appType
+    },
+  ]
+
+  return wrapForm
+} 
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/wrapsetting/index.jsx b/src/menu/components/table/normal-table/wrapsetting/index.jsx
deleted file mode 100644
index d5772f8..0000000
--- a/src/menu/components/table/normal-table/wrapsetting/index.jsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Icon, Modal } from 'antd'
-
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import SettingForm from './settingform'
-import './index.scss'
-
-class DataSource extends Component {
-  static propTpyes = {
-    config: PropTypes.any,
-    updateConfig: PropTypes.func
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    visible: false,
-    wrap: null
-  }
-
-  UNSAFE_componentWillMount () {
-    const { config } = this.props
-
-    this.setState({wrap: fromJS(config.wrap).toJS()})
-  }
-
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
-  }
-
-  editDataSource = () => {
-    this.setState({
-      visible: true
-    })
-  }
-
-  verifySubmit = () => {
-    const { config } = this.props
-
-    this.verifyRef.handleConfirm().then(res => {
-
-      this.setState({
-        wrap: res,
-        visible: false
-      })
-      this.props.updateConfig({...config, wrap: res})
-    })
-  }
-
-  render () {
-    const { config } = this.props
-    const { visible, dict, wrap } = this.state
-
-    return (
-      <div className="model-menu-setting-wrap">
-        <Icon type="edit" onClick={() => this.editDataSource()} />
-        <Modal
-          wrapClassName="popview-modal"
-          title="琛ㄦ牸璁剧疆"
-          visible={visible}
-          width={750}
-          maskClosable={false}
-          okText={dict['model.submit']}
-          onOk={this.verifySubmit}
-          onCancel={() => { this.setState({ visible: false }) }}
-          destroyOnClose
-        >
-          <SettingForm
-            dict={dict}
-            wrap={wrap}
-            config={config}
-            inputSubmit={this.verifySubmit}
-            wrappedComponentRef={(inst) => this.verifyRef = inst}
-          />
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default DataSource
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/wrapsetting/index.scss b/src/menu/components/table/normal-table/wrapsetting/index.scss
deleted file mode 100644
index 04372e6..0000000
--- a/src/menu/components/table/normal-table/wrapsetting/index.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.model-menu-setting-wrap {
-  display: inline-block;
-
-  >.anticon-edit {
-    color: #1890ff;
-  }
-}
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx b/src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx
deleted file mode 100644
index 049e55c..0000000
--- a/src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx
+++ /dev/null
@@ -1,283 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd'
-
-import ColorSketch from '@/mob/colorsketch'
-import './index.scss'
-
-class SettingForm extends Component {
-  static propTpyes = {
-    dict: PropTypes.object,      // 瀛楀吀椤�
-    config: PropTypes.object,    // 鍗$墖琛屼俊鎭�
-    wrap: PropTypes.object,      // 鏁版嵁婧愰厤缃�
-    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
-  }
-
-  state = {
-    roleList: [],
-    appType: sessionStorage.getItem('appType')
-  }
-
-  UNSAFE_componentWillMount () {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch (e) {
-        roleList = []
-      }
-    } else {
-      roleList = []
-    }
-
-    this.setState({roleList})
-  }
-
-  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 { wrap, config } = this.props
-    const { getFieldDecorator } = this.props.form
-    const { roleList, appType } = this.state
-
-    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="鏍囬">
-                {getFieldDecorator('title', {
-                  initialValue: wrap.title || ''
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�">
-                  <Icon type="question-circle" />
-                  缁勪欢鍚嶇О
-                </Tooltip>
-              }>
-                {getFieldDecorator('name', {
-                  initialValue: wrap.name,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!'
-                    }
-                  ]
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="琛ㄦ牸灞炴��">
-                {getFieldDecorator('tableType', {
-                  initialValue: wrap.tableType
-                })(
-                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
-                    <Radio key="" value=""> 涓嶅彲閫� </Radio>
-                    <Radio key="radio" value={'radio'}> 鍗曢�� </Radio>
-                    <Radio key="checkbox" value={'checkbox'}> 澶氶�� </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="杈规">
-                {getFieldDecorator('bordered', {
-                  initialValue: wrap.bordered || 'true'
-                })(
-                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
-                    <Radio key="true" value="true"> 鏈� </Radio>
-                    <Radio key="false" value="false"> 鏃� </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="琛ㄥご">
-                {getFieldDecorator('tableHeader', {
-                  initialValue: wrap.tableHeader || 'show'
-                })(
-                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
-                    <Radio key="show" value="show"> 鏄剧ず </Radio>
-                    <Radio key="hidden" value="hidden"> 闅愯棌 </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label="鍙敹璧�">
-                {getFieldDecorator('collapse', {
-                  initialValue: wrap.collapse || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio key="true" value="true"> 鏄� </Radio>
-                    <Radio key="false" value="false"> 鍚� </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            <Col span={12}>
-              <Form.Item label="琛ㄦ牸澶у皬">
-                {getFieldDecorator('size', {
-                  initialValue: wrap.size || 'middle'
-                })(
-                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
-                    <Radio key="default" value="default"> 澶� </Radio>
-                    <Radio key="middle" value="middle"> 涓� </Radio>
-                    <Radio key="small" value="small"> 灏� </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12} style={{height: '64px'}}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="榛樿鍊� #e8e8e8銆�">
-                  <Icon type="question-circle" />
-                  杈规棰滆壊
-                </Tooltip>
-              }>
-                {getFieldDecorator('borderColor', {
-                  initialValue: wrap.borderColor || '#e8e8e8'
-                })(
-                  <ColorSketch />
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="妯″紡">
-                {getFieldDecorator('mode', {
-                  initialValue: wrap.mode || 'default'
-                })(
-                  <Radio.Group>
-                    <Radio key="default" value="default"> 甯歌 </Radio>
-                    <Radio key="ghost" value="ghost"> 閫忔槑 </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12} style={{height: '64px'}}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="榛樿鍊� rgba(0, 0, 0, 0.65)銆�">
-                  <Icon type="question-circle" />
-                  瀛椾綋棰滆壊
-                </Tooltip>
-              }>
-                {getFieldDecorator('color', {
-                  initialValue: wrap.color || 'rgba(0, 0, 0, 0.65)'
-                })(
-                  <ColorSketch />
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="瀛椾綋澶у皬">
-                {getFieldDecorator('fontSize', {
-                  initialValue: wrap.fontSize || 14
-                })(<InputNumber min={14} max={30} precision={0} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
-                  <Icon type="question-circle" />
-                  瀹藉害
-                </Tooltip>
-              }>
-                {getFieldDecorator('width', {
-                  initialValue: wrap.width || 24,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '瀹藉害!'
-                    }
-                  ]
-                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��">
-                  <Icon type="question-circle" />
-                  楂樼骇鎼滅储
-                </Tooltip>
-              }>
-                {getFieldDecorator('advanceWidth', {
-                  initialValue: wrap.advanceWidth || 1000
-                })(<InputNumber min={10} max={3000} precision={0} onPressEnter={this.handleSubmit}/>)}
-              </Form.Item>
-            </Col> : null}
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鍙屽嚮琛ㄦ牸涓锛岃Е鍙戠殑鎸夐挳銆�">
-                  <Icon type="question-circle" />
-                  鍙屽嚮浜嬩欢
-                </Tooltip>
-              }>
-                {getFieldDecorator('doubleClick', {
-                  initialValue: wrap.doubleClick || ''
-                })(
-                  <Select allowClear>
-                    {config.action.map(option =>
-                      <Select.Option key={option.uuid} value={option.uuid}>{option.label}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col> : null}
-            <Col span={12}>
-              <Form.Item label="榛戝悕鍗�">
-                {getFieldDecorator('blacklist', {
-                  initialValue: wrap.blacklist || []
-                })(
-                  <Select
-                    showSearch
-                    mode="multiple"
-                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  >
-                    {roleList.map(option =>
-                      <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-          </Row>
-        </Form>
-      </div>
-    )
-  }
-}
-
-export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/wrapsetting/settingform/index.scss b/src/menu/components/table/normal-table/wrapsetting/settingform/index.scss
deleted file mode 100644
index c530b18..0000000
--- a/src/menu/components/table/normal-table/wrapsetting/settingform/index.scss
+++ /dev/null
@@ -1,15 +0,0 @@
-.model-menu-setting-form {
-  position: relative;
-
-  .anticon-question-circle {
-    color: #c49f47;
-    margin-right: 3px;
-  }
-  .ant-input-number {
-    width: 100%;
-  }
-  .color-sketch-block {
-    position: relative;
-    top: 7px;
-  }
-}
\ No newline at end of file
diff --git a/src/menu/components/tabs/antv-tabs/index.jsx b/src/menu/components/tabs/antv-tabs/index.jsx
index 41e0b3d..31c2f9c 100644
--- a/src/menu/components/tabs/antv-tabs/index.jsx
+++ b/src/menu/components/tabs/antv-tabs/index.jsx
@@ -10,12 +10,11 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MenuUtils from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
-import getTabForm from './options'
+import { getTabForm, getTabsSetForm } from './options'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import './index.scss'
 
-const SettingComponent = asyncIconComponent(() => import('../tabsetting'))
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
@@ -342,6 +341,16 @@
     this.props.updateConfig(tabs)
   }
 
+  getTabsForms = () => {
+    const { tabs } = this.state
+
+    return getTabsSetForm(tabs.setting)
+  }
+
+  updateTabs = (res) => {
+    this.updateComponent({...this.state.tabs, setting: res})
+  }
+
   onChange = (key) => {
     const { tabs } = this.state
     window.GLOB.TabsMap.set(tabs.uuid, key)
@@ -379,7 +388,9 @@
             <NormalForm title="娣诲姞鏍囩" width={600} update={this.updateTab} getForms={() => this.getTabForms()}>
               <Icon type="plus" className="plus" title="娣诲姞鏍囩"/>
             </NormalForm>
-            <SettingComponent config={tabs} updateConfig={this.updateComponent} />
+            <NormalForm title="鏍囩椤佃缃�" width={700} update={this.updateTabs} getForms={this.getTabsForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="tabs" card={tabs}/>
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(tabs.uuid)} />
diff --git a/src/menu/components/tabs/antv-tabs/options.jsx b/src/menu/components/tabs/antv-tabs/options.jsx
index db65e1c..11ca9a3 100644
--- a/src/menu/components/tabs/antv-tabs/options.jsx
+++ b/src/menu/components/tabs/antv-tabs/options.jsx
@@ -1,7 +1,7 @@
 /**
- * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ * @description tab琛ㄥ崟閰嶇疆淇℃伅
  */
-export default function (tab, setting) {
+export function getTabForm(tab, setting) {
   let appType = sessionStorage.getItem('appType')
   let roleList = sessionStorage.getItem('sysRoles')
 
@@ -60,4 +60,96 @@
   ]
 
   return tabForm
+}
+
+/**
+ * @description tabs琛ㄥ崟閰嶇疆淇℃伅
+ */
+export function getTabsSetForm(setting) {
+  let appType = sessionStorage.getItem('appType')
+  let roleList = sessionStorage.getItem('sysRoles')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch (e) {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const tabForm = [
+    {
+      type: 'text',
+      field: 'name',
+      label: '缁勪欢鍚嶇О',
+      initval: setting.name || '',
+      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: setting.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'select',
+      field: 'position',
+      label: '鏍囩浣嶇疆',
+      initval: setting.position || 'top',
+      required: true,
+      options: [
+        {value: 'top', label: 'top'},
+        {value: 'bottom', label: 'bottom'},
+        {value: 'left', label: 'left'},
+        {value: 'right', label: 'right'},
+      ],
+      controlFields: [
+        {field: 'display', values: ['top', 'bottom']},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'tabStyle',
+      label: '椤电鏍峰紡',
+      initval: setting.tabStyle || 'line',
+      tooltip: '鏍囩浣嶇疆涓簍op鏃舵湁鏁堬紝榛樿鍊间负line銆�',
+      required: true,
+      options: [
+        {value: 'line', label: 'line'},
+        {value: 'card', label: 'card'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'display',
+      label: '鏍囩鏄剧ず',
+      initval: setting.display || 'flex',
+      required: false,
+      options: [
+        {value: 'flex', label: '寮规�у竷灞�'},
+        {value: 'inline-block', label: '瀹氬'},
+      ],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: setting.blacklist || [],
+      required: false,
+      options: roleList,
+      forbid: !!appType
+    },
+  ]
+
+  return tabForm
 } 
\ No newline at end of file
diff --git a/src/menu/components/tabs/tabsetting/index.jsx b/src/menu/components/tabs/tabsetting/index.jsx
deleted file mode 100644
index 3b61f0f..0000000
--- a/src/menu/components/tabs/tabsetting/index.jsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Icon, Modal } from 'antd'
-
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import SettingForm from './settingform'
-import './index.scss'
-
-class DataSource extends Component {
-  static propTpyes = {
-    config: PropTypes.any,
-    updateConfig: PropTypes.func
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    visible: false,
-    setting: null
-  }
-
-  UNSAFE_componentWillMount () {
-    const { config } = this.props
-
-    this.setState({setting: fromJS(config.setting).toJS()})
-  }
-
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
-  }
-
-  editDataSource = () => {
-    this.setState({
-      visible: true
-    })
-  }
-
-  verifySubmit = () => {
-    const { config } = this.props
-
-    this.verifyRef.handleConfirm().then(res => {
-
-      this.setState({
-        setting: res,
-        visible: false
-      })
-      this.props.updateConfig({...config, setting: res})
-    })
-  }
-
-  render () {
-    const { visible, dict, setting } = this.state
-
-    return (
-      <div className="model-menu-setting-wrap">
-        <Icon type="edit" onClick={() => this.editDataSource()} />
-        <Modal
-          wrapClassName="popview-modal"
-          title={'鏍囩椤甸厤缃�'}
-          visible={visible}
-          width={700}
-          maskClosable={false}
-          okText={dict['model.submit']}
-          onOk={this.verifySubmit}
-          onCancel={() => { this.setState({ visible: false }) }}
-          destroyOnClose
-        >
-          <SettingForm
-            dict={dict}
-            setting={setting}
-            inputSubmit={this.verifySubmit}
-            wrappedComponentRef={(inst) => this.verifyRef = inst}
-          />
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default DataSource
\ No newline at end of file
diff --git a/src/menu/components/tabs/tabsetting/index.scss b/src/menu/components/tabs/tabsetting/index.scss
deleted file mode 100644
index 04372e6..0000000
--- a/src/menu/components/tabs/tabsetting/index.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.model-menu-setting-wrap {
-  display: inline-block;
-
-  >.anticon-edit {
-    color: #1890ff;
-  }
-}
\ No newline at end of file
diff --git a/src/menu/components/tabs/tabsetting/settingform/index.jsx b/src/menu/components/tabs/tabsetting/settingform/index.jsx
deleted file mode 100644
index 95b3f8b..0000000
--- a/src/menu/components/tabs/tabsetting/settingform/index.jsx
+++ /dev/null
@@ -1,179 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd'
-
-import './index.scss'
-
-class SettingForm extends Component {
-  static propTpyes = {
-    dict: PropTypes.object,       // 瀛楀吀椤�
-    setting: PropTypes.object,    // 鏁版嵁婧愰厤缃�
-    inputSubmit: PropTypes.func   // 鍥炶溅浜嬩欢
-  }
-
-  state = {
-    appType: sessionStorage.getItem('appType'),
-    position: this.props.setting.position,
-    roleList: []
-  }
-
-  UNSAFE_componentWillMount () {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch (e) {
-        roleList = []
-      }
-    } else {
-      roleList = []
-    }
-
-    this.setState({roleList})
-  }
-
-  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 } = this.props
-    const { getFieldDecorator } = this.props.form
-    const { roleList, appType, position } = this.state
-
-    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('name', {
-                  initialValue: setting.name,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!'
-                    }
-                  ]
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit}/>)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
-                  <Icon type="question-circle" />
-                  瀹藉害
-                </Tooltip>
-              }>
-                {getFieldDecorator('width', {
-                  initialValue: setting.width || 24,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '瀹藉害!'
-                    }
-                  ]
-                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit}/>)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="鏍囩浣嶇疆">
-                {getFieldDecorator('position', {
-                  initialValue: setting.position || 'top'
-                })(
-                  <Select onChange={(val) => this.setState({position: val})}>
-                    <Select.Option key="top" value="top"> top </Select.Option>
-                    <Select.Option key="bottom" value="bottom"> bottom </Select.Option>
-                    <Select.Option key="left" value="left"> left </Select.Option>
-                    <Select.Option key="right" value="right"> right </Select.Option>
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍囩浣嶇疆涓簍op鏃舵湁鏁堬紝榛樿鍊间负line銆�">
-                  <Icon type="question-circle" />
-                  椤电鏍峰紡
-                </Tooltip>
-              }>
-                {getFieldDecorator('tabStyle', {
-                  initialValue: setting.tabStyle || 'line'
-                })(
-                  <Radio.Group>
-                    <Radio value="line">line</Radio>
-                    <Radio value="card">card</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {appType === 'mob' && (position === 'top' || position === 'bottom') ? <Col span={12}>
-              <Form.Item label="鏍囩鏄剧ず">
-                {getFieldDecorator('display', {
-                  initialValue: setting.display || 'flex'
-                })(
-                  <Radio.Group>
-                    <Radio value="flex">寮规�у竷灞�</Radio>
-                    <Radio value="inline-block">瀹氬</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            <Col span={12}>
-              <Form.Item label="榛戝悕鍗�">
-                {getFieldDecorator('blacklist', {
-                  initialValue: setting.blacklist || []
-                })(
-                  <Select
-                    showSearch
-                    mode="multiple"
-                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  >
-                    {roleList.map(option =>
-                      <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-          </Row>
-        </Form>
-      </div>
-    )
-  }
-}
-
-export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/tabs/tabsetting/settingform/index.scss b/src/menu/components/tabs/tabsetting/settingform/index.scss
deleted file mode 100644
index 159130b..0000000
--- a/src/menu/components/tabs/tabsetting/settingform/index.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.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/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx
index f392778..06040f1 100644
--- a/src/menu/components/tree/antd-tree/index.jsx
+++ b/src/menu/components/tree/antd-tree/index.jsx
@@ -7,17 +7,18 @@
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
+import getWrapForm from './options'
 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 NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
-const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
 
 const { TreeNode } = Tree
 
@@ -141,6 +142,16 @@
     this.props.updateConfig(config)
   }
 
+  getWrapForms = () => {
+    const { wrap, columns } = this.state.card
+
+    return getWrapForm(wrap, columns)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -157,7 +168,9 @@
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            <WrapComponent config={card} updateConfig={this.updateComponent} />
+            <NormalForm title="鍩烘湰璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="normaltable" card={card}/>
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
diff --git a/src/menu/components/tree/antd-tree/options.jsx b/src/menu/components/tree/antd-tree/options.jsx
new file mode 100644
index 0000000..a968ff0
--- /dev/null
+++ b/src/menu/components/tree/antd-tree/options.jsx
@@ -0,0 +1,125 @@
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (wrap, columns = []) {
+  let roleList = sessionStorage.getItem('sysRoles')
+  let appType = sessionStorage.getItem('appType')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch (e) {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const wrapForm = [
+    {
+      type: 'text',
+      field: 'title',
+      label: '鏍囬',
+      initval: wrap.title || '',
+      required: false
+    },
+    {
+      type: 'text',
+      field: 'name',
+      label: '缁勪欢鍚嶇О',
+      initval: wrap.name || '',
+      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
+      required: true
+    },
+    {
+      type: 'select',
+      field: 'valueField',
+      label: 'Value',
+      initval: wrap.valueField || '',
+      tooltip: '鏁版嵁鍊煎瓧娈点��',
+      required: true,
+      options: columns
+    },
+    {
+      type: 'select',
+      field: 'labelField',
+      label: 'Label',
+      initval: wrap.labelField || '',
+      tooltip: '鏄剧ず鏂囧瓧瀛楁銆�',
+      required: true,
+      options: columns
+    },
+    {
+      type: 'select',
+      field: 'parentField',
+      label: 'Parent',
+      initval: wrap.parentField || '',
+      tooltip: '鐖剁骇瀛楁銆�',
+      required: true,
+      options: columns
+    },
+    {
+      type: 'text',
+      field: 'mark',
+      label: '椤剁骇鏍囪瘑',
+      initval: wrap.mark || '',
+      tooltip: '鐖剁骇瀛楁鍊间笌椤剁骇鏍囪瘑鐩稿悓鏃讹紝瑙嗕负椤剁骇鑺傜偣銆�',
+      required: false
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: wrap.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'radio',
+      field: 'showIcon',
+      label: '鍥炬爣',
+      initval: wrap.showIcon || 'false',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'showLine',
+      label: '鍒嗗壊绾�',
+      initval: wrap.showLine || 'false',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'searchable',
+      label: '杩囨护鏉′欢',
+      initval: wrap.searchable || 'false',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: wrap.blacklist || [],
+      required: false,
+      options: roleList,
+      forbid: !!appType
+    },
+  ]
+
+  return wrapForm
+} 
\ No newline at end of file
diff --git a/src/menu/components/tree/antd-tree/wrapsetting/index.jsx b/src/menu/components/tree/antd-tree/wrapsetting/index.jsx
deleted file mode 100644
index 595cb9e..0000000
--- a/src/menu/components/tree/antd-tree/wrapsetting/index.jsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Icon, Modal } from 'antd'
-
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import SettingForm from './settingform'
-import './index.scss'
-
-class DataSource extends Component {
-  static propTpyes = {
-    config: PropTypes.any,
-    updateConfig: PropTypes.func
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    visible: false,
-    wrap: null
-  }
-
-  UNSAFE_componentWillMount () {
-    const { config } = this.props
-
-    this.setState({wrap: fromJS(config.wrap).toJS()})
-  }
-
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
-  }
-
-  editDataSource = () => {
-    this.setState({
-      visible: true
-    })
-  }
-
-  verifySubmit = () => {
-    const { config } = this.props
-
-    this.verifyRef.handleConfirm().then(res => {
-
-      this.setState({
-        wrap: res,
-        visible: false
-      })
-      this.props.updateConfig({...config, wrap: res})
-    })
-  }
-
-  render () {
-    const { config } = this.props
-    const { visible, dict, wrap } = this.state
-
-    return (
-      <div className="model-menu-setting-wrap">
-        <Icon type="edit" onClick={() => this.editDataSource()} />
-        <Modal
-          wrapClassName="popview-modal"
-          title="鍩烘湰璁剧疆"
-          visible={visible}
-          width={700}
-          maskClosable={false}
-          okText={dict['model.submit']}
-          onOk={this.verifySubmit}
-          onCancel={() => { this.setState({ visible: false }) }}
-          destroyOnClose
-        >
-          <SettingForm
-            dict={dict}
-            wrap={wrap}
-            config={config}
-            inputSubmit={this.verifySubmit}
-            wrappedComponentRef={(inst) => this.verifyRef = inst}
-          />
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default DataSource
\ No newline at end of file
diff --git a/src/menu/components/tree/antd-tree/wrapsetting/index.scss b/src/menu/components/tree/antd-tree/wrapsetting/index.scss
deleted file mode 100644
index 04372e6..0000000
--- a/src/menu/components/tree/antd-tree/wrapsetting/index.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.model-menu-setting-wrap {
-  display: inline-block;
-
-  >.anticon-edit {
-    color: #1890ff;
-  }
-}
\ No newline at end of file
diff --git a/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx b/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx
deleted file mode 100644
index 08958d3..0000000
--- a/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx
+++ /dev/null
@@ -1,262 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd'
-
-import './index.scss'
-
-class SettingForm extends Component {
-  static propTpyes = {
-    dict: PropTypes.object,      // 瀛楀吀椤�
-    config: PropTypes.object,    // 鍗$墖琛屼俊鎭�
-    wrap: PropTypes.object,      // 鏁版嵁婧愰厤缃�
-    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
-  }
-
-  state = {
-    roleList: [],
-  }
-
-  UNSAFE_componentWillMount () {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch (e) {
-        roleList = []
-      }
-    } else {
-      roleList = []
-    }
-
-    this.setState({roleList})
-  }
-
-  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 { wrap, config } = this.props
-    const { getFieldDecorator } = this.props.form
-    const { roleList } = this.state
-
-    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="鏍囬">
-                {getFieldDecorator('title', {
-                  initialValue: wrap.title || ''
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�">
-                  <Icon type="question-circle" />
-                  缁勪欢鍚嶇О
-                </Tooltip>
-              }>
-                {getFieldDecorator('name', {
-                  initialValue: wrap.name,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!'
-                    }
-                  ]
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏁版嵁鍊煎瓧娈点��">
-                  <Icon type="question-circle" />
-                  Value
-                </Tooltip>
-              }>
-                {getFieldDecorator('valueField', {
-                  initialValue: wrap.valueField || '',
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.select'] + 'Value瀛楁!'
-                    }
-                  ]
-                })(
-                  <Select>
-                    {config.columns.map(option =>
-                      <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏄剧ず鏂囧瓧瀛楁銆�">
-                  <Icon type="question-circle" />
-                  Label
-                </Tooltip>
-              }>
-                {getFieldDecorator('labelField', {
-                  initialValue: wrap.labelField || '',
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.select'] + 'Label瀛楁!'
-                    }
-                  ]
-                })(
-                  <Select>
-                    {config.columns.map(option =>
-                      <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鐖剁骇瀛楁銆�">
-                  <Icon type="question-circle" />
-                  Parent
-                </Tooltip>
-              }>
-                {getFieldDecorator('parentField', {
-                  initialValue: wrap.parentField || '',
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.select'] + 'Parent瀛楁!'
-                    }
-                  ]
-                })(
-                  <Select>
-                    {config.columns.map(option =>
-                      <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title={'鐖剁骇瀛楁鍊间笌椤剁骇鏍囪瘑鐩稿悓鏃讹紝瑙嗕负椤剁骇鑺傜偣銆�'}>
-                  <Icon type="question-circle" />
-                  椤剁骇鏍囪瘑
-                </Tooltip>
-              }>
-                {getFieldDecorator('mark', {
-                  initialValue: wrap.mark || ''
-                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
-                  <Icon type="question-circle" />
-                  瀹藉害
-                </Tooltip>
-              }>
-                {getFieldDecorator('width', {
-                  initialValue: wrap.width || 24,
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '瀹藉害!'
-                    }
-                  ]
-                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="鍥炬爣">
-                {getFieldDecorator('showIcon', {
-                  initialValue: wrap.showIcon || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄剧ず</Radio>
-                    <Radio value="false">闅愯棌</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="鍒嗗壊绾�">
-                {getFieldDecorator('showLine', {
-                  initialValue: wrap.showLine || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄剧ず</Radio>
-                    <Radio value="false">闅愯棌</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="杩囨护鏉′欢">
-                {getFieldDecorator('searchable', {
-                  initialValue: wrap.searchable || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄剧ず</Radio>
-                    <Radio value="false">闅愯棌</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="榛戝悕鍗�">
-                {getFieldDecorator('blacklist', {
-                  initialValue: wrap.blacklist || []
-                })(
-                  <Select
-                    showSearch
-                    mode="multiple"
-                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  >
-                    {roleList.map(option =>
-                      <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col>
-          </Row>
-        </Form>
-      </div>
-    )
-  }
-}
-
-export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss b/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss
deleted file mode 100644
index c530b18..0000000
--- a/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss
+++ /dev/null
@@ -1,15 +0,0 @@
-.model-menu-setting-form {
-  position: relative;
-
-  .anticon-question-circle {
-    color: #c49f47;
-    margin-right: 3px;
-  }
-  .ant-input-number {
-    width: 100%;
-  }
-  .color-sketch-block {
-    position: relative;
-    top: 7px;
-  }
-}
\ No newline at end of file
diff --git a/src/mob/components/tabs/antv-tabs/index.jsx b/src/mob/components/tabs/antv-tabs/index.jsx
index 0c7d839..6a26189 100644
--- a/src/mob/components/tabs/antv-tabs/index.jsx
+++ b/src/mob/components/tabs/antv-tabs/index.jsx
@@ -10,12 +10,11 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MenuUtils from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
-import getTabForm from './options'
+import { getTabForm, getTabsSetForm } from './options'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import './index.scss'
 
-const SettingComponent = asyncIconComponent(() => import('@/menu/components/tabs/tabsetting'))
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
@@ -357,6 +356,16 @@
     this.props.updateConfig(tabs)
   }
 
+  getTabsForms = () => {
+    const { tabs } = this.state
+
+    return getTabsSetForm(tabs.setting)
+  }
+
+  updateTabs = (res) => {
+    this.updateComponent({...this.state.tabs, setting: res})
+  }
+
   onChange = (key) => {
     const { tabs } = this.state
     window.GLOB.TabsMap.set(tabs.uuid, key)
@@ -403,7 +412,9 @@
             <NormalForm title="娣诲姞鏍囩" width={600} update={this.updateTab} getForms={() => this.getTabForms()}>
               <Icon type="plus" className="plus" title="娣诲姞鏍囩"/>
             </NormalForm>
-            <SettingComponent config={tabs} updateConfig={this.updateComponent} />
+            <NormalForm title="鏍囩椤佃缃�" width={700} update={this.updateTabs} getForms={this.getTabsForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="tabs" card={tabs}/>
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(tabs.uuid)} />
diff --git a/src/mob/components/tabs/antv-tabs/options.jsx b/src/mob/components/tabs/antv-tabs/options.jsx
index db65e1c..5d4291a 100644
--- a/src/mob/components/tabs/antv-tabs/options.jsx
+++ b/src/mob/components/tabs/antv-tabs/options.jsx
@@ -1,7 +1,7 @@
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
-export default function (tab, setting) {
+export function getTabForm(tab, setting) {
   let appType = sessionStorage.getItem('appType')
   let roleList = sessionStorage.getItem('sysRoles')
 
@@ -60,4 +60,96 @@
   ]
 
   return tabForm
-} 
\ No newline at end of file
+}
+
+/**
+ * @description tabs琛ㄥ崟閰嶇疆淇℃伅
+ */
+export function getTabsSetForm(setting) {
+  let appType = sessionStorage.getItem('appType')
+  let roleList = sessionStorage.getItem('sysRoles')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch (e) {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const tabForm = [
+    {
+      type: 'text',
+      field: 'name',
+      label: '缁勪欢鍚嶇О',
+      initval: setting.name || '',
+      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: setting.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'select',
+      field: 'position',
+      label: '鏍囩浣嶇疆',
+      initval: setting.position || 'top',
+      required: true,
+      options: [
+        {value: 'top', label: 'top'},
+        {value: 'bottom', label: 'bottom'},
+        {value: 'left', label: 'left'},
+        {value: 'right', label: 'right'},
+      ],
+      controlFields: [
+        {field: 'display', values: ['top', 'bottom']},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'tabStyle',
+      label: '椤电鏍峰紡',
+      initval: setting.tabStyle || 'line',
+      tooltip: '鏍囩浣嶇疆涓簍op鏃舵湁鏁堬紝榛樿鍊间负line銆�',
+      required: true,
+      options: [
+        {value: 'line', label: 'line'},
+        {value: 'card', label: 'card'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'display',
+      label: '鏍囩鏄剧ず',
+      initval: setting.display || 'flex',
+      required: false,
+      options: [
+        {value: 'flex', label: '寮规�у竷灞�'},
+        {value: 'inline-block', label: '瀹氬'},
+      ],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: setting.blacklist || [],
+      required: false,
+      options: roleList,
+      forbid: !!appType
+    },
+  ]
+
+  return tabForm
+}
\ No newline at end of file
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
index 6fb2b09..dccd8db 100644
--- a/src/views/rolemanage/index.jsx
+++ b/src/views/rolemanage/index.jsx
@@ -417,7 +417,9 @@
                   try {
                     let pageParam = JSON.parse(window.decodeURIComponent(window.atob(item.menus_rolelist)))
                     item.nodes = pageParam
-                    if (pageParam.type === 'navbar') {
+                    if (pageParam.login) {
+                      item.nodes = ''
+                    } else if (pageParam.type === 'navbar') {
                       item.type = 'navbar'
                     }
                   } catch (e) {

--
Gitblit v1.8.0