From fe5721c8efd837b13b7f2d2687da53637fc02919 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 05 八月 2021 15:05:02 +0800
Subject: [PATCH] 2021-08-05

---
 src/tabviews/formtab/actionList/index.jsx                         |    4 
 src/templates/subtableconfig/source.jsx                           |    3 
 src/menu/components/card/table-card/index.jsx                     |  177 ++++++-
 src/menu/components/card/balcony/options.jsx                      |    4 
 src/locales/zh-CN/model.js                                        |    1 
 src/menu/components/card/cardsimplecomponent/options.jsx          |  174 +++++++
 src/templates/formtabconfig/dragelement/index.jsx                 |    1 
 src/menu/components/chart/antv-bar/index.jsx                      |    1 
 src/menu/components/chart/antv-scatter/index.jsx                  |    1 
 src/locales/en-US/model.js                                        |    1 
 src/templates/formtabconfig/source.jsx                            |    2 
 src/menu/components/carousel/data-card/index.jsx                  |   21 
 src/views/menudesign/index.jsx                                    |    7 
 src/menu/components/card/cardsimplecomponent/index.scss           |    0 
 src/menu/components/card/balcony/index.jsx                        |   17 
 src/menu/components/carousel/data-card/options.jsx                |  133 +++++
 src/menu/components/card/cardcellcomponent/index.jsx              |    6 
 src/menu/components/card/data-card/options.jsx                    |  163 +++++++
 src/views/pcdesign/index.jsx                                      |    7 
 src/templates/comtableconfig/source.jsx                           |    3 
 src/menu/components/carousel/prop-card/index.jsx                  |   21 
 src/menu/components/card/cardcomponent/index.jsx                  |   60 +-
 src/menu/components/card/data-card/index.jsx                      |  272 +++++++++--
 src/menu/components/card/cardsimplecomponent/index.jsx            |  111 ++--
 /dev/null                                                         |   11 
 src/templates/sharecomponent/actioncomponent/dragaction/index.jsx |    1 
 src/menu/components/card/prop-card/index.jsx                      |  151 +++++-
 src/menu/components/table/normal-table/index.jsx                  |    1 
 28 files changed, 1,073 insertions(+), 281 deletions(-)

diff --git a/src/locales/en-US/model.js b/src/locales/en-US/model.js
index 2d2ef4b..cdff5ec 100644
--- a/src/locales/en-US/model.js
+++ b/src/locales/en-US/model.js
@@ -91,7 +91,6 @@
   'model.form.afterSuccess': 'Success',
   'model.form.afterError': 'Failure',
   'header.form.messageTip': 'Message',
-  'header.form.errorTime': 'Residence time',
   'header.form.refresh': 'Refresh',
   'header.form.refresh.never': 'Don\'t refresh',
   'header.form.refresh.grid': 'Refresh the table',
diff --git a/src/locales/zh-CN/model.js b/src/locales/zh-CN/model.js
index 5a3a4cd..d2667aa 100644
--- a/src/locales/zh-CN/model.js
+++ b/src/locales/zh-CN/model.js
@@ -91,7 +91,6 @@
   'model.form.afterSuccess': '鎴愬姛鍚�',
   'model.form.afterError': '澶辫触鍚�',
   'header.form.messageTip': '淇℃伅鎻愮ず',
-  'header.form.errorTime': '鍋滅暀鏃堕棿',
   'header.form.refresh': '鍒锋柊',
   'header.form.refresh.never': '涓嶅埛鏂�',
   'header.form.refresh.grid': '鍒锋柊琛ㄦ牸',
diff --git a/src/menu/components/card/balcony/index.jsx b/src/menu/components/card/balcony/index.jsx
index 636ba78..9683031 100644
--- a/src/menu/components/card/balcony/index.jsx
+++ b/src/menu/components/card/balcony/index.jsx
@@ -164,24 +164,9 @@
   addButton = () => {
     const { card } = this.state
 
-    let newcard = {}
+    let newcard = {eleType: 'button', label: 'button', verify: null, show: 'link', sqlType: '', Ot: 'requiredSgl', OpenType: 'prompt', icon: '', class: 'primary', intertype: 'system', execSuccess: 'grid', execError: 'never', popClose: 'never'}
     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.execSuccess = 'grid'
-    newcard.execError = 'never'
-    newcard.popClose = 'never'
-    newcard.errorTime = 10
-    newcard.verify = null
-    newcard.show = 'link'
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
     MKEmitter.emit('cardAddElement', [card.uuid, card.uuid], newcard)
diff --git a/src/menu/components/card/balcony/options.jsx b/src/menu/components/card/balcony/options.jsx
index b1684a8..4bb345d 100644
--- a/src/menu/components/card/balcony/options.jsx
+++ b/src/menu/components/card/balcony/options.jsx
@@ -82,8 +82,8 @@
       type: 'radio',
       field: 'supControl',
       label: '鏄剧ず鎺у埗',
-      tooltip: '褰撳墠缁勪欢鍦ㄤ富琛ㄩ�変腑琛屾椂鏄剧ず锛岃繕鏄缁堟樉绀恒��',
       initval: wrap.supControl || 'show',
+      tooltip: '褰撳墠缁勪欢鍦ㄤ富琛ㄩ�変腑琛屾椂鏄剧ず锛岃繕鏄缁堟樉绀恒��',
       required: false,
       options: [
         {value: 'hidden', label: '閫夎'},
@@ -206,7 +206,7 @@
       type: 'multiselect',
       field: 'blacklist',
       label: '榛戝悕鍗�',
-      initval: wrap.blacklist || '',
+      initval: wrap.blacklist || [],
       required: false,
       options: roleList
     },
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 3c5154c..3a03296 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -297,11 +297,15 @@
    * @description 鍙栨秷淇濆瓨锛屽鏋滃厓绱犱负鏂版坊鍏冪礌锛屽垯浠庡簭鍒椾腑鍒犻櫎
    */
   editModalCancel = () => {
-    const { card, elements } = this.state
+    const { card, elements, appType } = this.state
     let _elements = null
 
     if (card.focus) {
       _elements = elements.filter(item => item.uuid !== card.uuid)
+      
+      if (card.OpenType === 'popview' && appType !== 'mob') { // 寮圭獥鏍囩鎸夐挳锛屼粠澶嶅埗鍒楄〃涓垹闄�
+        MKEmitter.emit('delButtons', [card.uuid])
+      }
     } else {
       _elements = elements
     }
diff --git a/src/menu/components/card/cardcomponent/index.jsx b/src/menu/components/card/cardcomponent/index.jsx
index de93665..895c2e3 100644
--- a/src/menu/components/card/cardcomponent/index.jsx
+++ b/src/menu/components/card/cardcomponent/index.jsx
@@ -14,7 +14,7 @@
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-const PasteComponent = asyncIconComponent(() => import('./pastecomponent'))
+const PasteController = asyncIconComponent(() => import('@/components/paste'))
 
 class CardBoxComponent extends Component {
   static propTpyes = {
@@ -85,7 +85,7 @@
     this.props.updateElement(_card)
   }
 
-  updateCard = (elements, type) => {
+  updateCard = (elements) => {
     const { card, side } = this.state
 
     let _card = {}
@@ -96,16 +96,9 @@
       _card = {...card, elements: elements}
     }
 
-    if (type === 'paste') {
-      this.setState({
-        card: _card,
-        elements: fromJS(elements).toJS()
-      })
-    } else {
-      this.setState({
-        card: _card
-      })
-    }
+    this.setState({
+      card: _card
+    })
 
     this.props.updateElement(_card)
   }
@@ -151,24 +144,9 @@
     const { cards } = this.props
     const { card } = this.state
 
-    let newcard = {}
+    let newcard = {eleType: 'button', label: 'button', verify: null, show: 'link', sqlType: '', Ot: 'requiredSgl', OpenType: 'prompt', icon: '', class: 'primary', intertype: 'system', execSuccess: 'grid', execError: 'never', popClose: 'never'}
     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.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)
@@ -202,8 +180,8 @@
 
     if (res.appmenu) {
       res.menu = res.appmenu
-      delete res.appmenu
     }
+    delete res.appmenu
 
     this.setState({
       card: {...card, setting: res}
@@ -217,6 +195,28 @@
     }
 
     this.props.updateElement({...card, setting: res})
+  }
+
+  paste = (element, resolve) => {
+    const { cards } = this.props
+    const { card } = this.state
+
+    let _uuid = Utils.getuuid()
+    
+    if (element.copyType === 'action' && element.OpenType === 'popview') { // 寮圭獥鏍囩澶嶅埗
+      let _cell = fromJS(element).toJS()
+      _cell.$originUuid = element.uuid
+      _cell.uuid = _uuid
+      MKEmitter.emit('copyButtons', [_cell])
+    }
+
+    element.uuid = _uuid
+    element.focus = true
+
+    resolve({status: true})
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], element)
   }
 
   clickComponent = (e) => {
@@ -265,7 +265,7 @@
                   <Icon type="edit" className="edit" title="缂栬緫"/>
                 </NormalForm>
                 <CopyComponent type="cardcell" card={card}/>
-                <PasteComponent elements={elements} options={['action', 'customCardElement']} updateConfig={(list) => this.updateCard(list, 'paste')} />
+                <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} />
                 <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
                 <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                   <div className="mk-popover-control">
diff --git a/src/menu/components/card/cardcomponent/pastecomponent/index.jsx b/src/menu/components/card/cardcomponent/pastecomponent/index.jsx
deleted file mode 100644
index bc98b34..0000000
--- a/src/menu/components/card/cardcomponent/pastecomponent/index.jsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { fromJS } from 'immutable'
-import { Icon, Modal, notification } from 'antd'
-
-import Utils from '@/utils/utils.js'
-import MKEmitter from '@/utils/events.js'
-import asyncComponent from '@/utils/asyncComponent'
-import './index.scss'
-
-const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
-
-class PasteController extends Component {
-  static propTpyes = {
-    config: PropTypes.object,        // 缁勪欢閰嶇疆
-    updateConfig: PropTypes.func
-  }
-
-  state = {
-    visible: false
-  }
-
-  handleMenuClick = () => {
-    this.setState({visible: true})
-  }
-
-  pasteSubmit = () => {
-    const { options, elements } = this.props
-    this.pasteFormRef.handleConfirm().then(res => {
-      if (!options.includes(res.copyType)) {
-        notification.warning({ top: 92, message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�', duration: 5 })
-        return
-      }
-
-      let _uuid = Utils.getuuid()
-      if (res.copyType === 'action' && res.OpenType === 'popview') {
-        let _cell = fromJS(res).toJS()
-        _cell.$originUuid = res.uuid
-        _cell.uuid = _uuid
-        MKEmitter.emit('copyButtons', [_cell])
-      }
-      res.uuid = _uuid
-
-      this.props.updateConfig([...elements, res])
-      this.setState({visible: false})
-
-      notification.success({
-        top: 92,
-        message: '绮樿创鎴愬姛锛�',
-        duration: 2
-      })
-    })
-  }
-
-  render() {
-    const { visible } = this.state
-
-    return (
-      <div style={{display: 'inline-block'}}>
-        <Icon type="snippets" style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} />
-        <Modal
-          title="绮樿创"
-          visible={visible}
-          width={600}
-          maskClosable={false}
-          onOk={this.pasteSubmit}
-          onCancel={() => {this.setState({visible: false})}}
-          destroyOnClose
-        >
-          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default PasteController
\ No newline at end of file
diff --git a/src/menu/components/card/table-card/cardcomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
similarity index 65%
rename from src/menu/components/card/table-card/cardcomponent/index.jsx
rename to src/menu/components/card/cardsimplecomponent/index.jsx
index a46143b..f6dff48 100644
--- a/src/menu/components/card/table-card/cardcomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -1,36 +1,32 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Modal, Popover, Icon } from 'antd'
+import { Popover, Icon } from 'antd'
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import SettingForm from './settingform'
 import { resetStyle } from '@/utils/utils-custom.js'
+import { getTableSetting, getCarouselSetting } from './options'
 import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
-const CardCellComponent = asyncComponent(() => import('../../cardcellcomponent'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
+const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 
 class CardBoxComponent extends Component {
   static propTpyes = {
     cards: PropTypes.object,         // 鍗$墖琛岄厤缃俊鎭�
     card: PropTypes.object,          // 鍗$墖閰嶇疆淇℃伅
+    move: PropTypes.func,            // 鍗$墖绉诲姩
     deleteElement: PropTypes.func,   // 鍗$墖鍒犻櫎
     updateElement: PropTypes.func    // 鑿滃崟閰嶇疆鏇存柊
   }
 
   state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    card: null,            // 鍗$墖淇℃伅锛屽寘鎷鍙嶉潰
+    card: null,            // 鍗$墖淇℃伅
     formlist: null,        // 璁剧疆琛ㄥ崟淇℃伅
-    elements: null,        // 缂栬緫缁�
-    visible: false,        // 妯℃�佹鎺у埗
-    settingVisible: false,
   }
 
   /**
@@ -40,8 +36,7 @@
     const { card } = this.props
 
     this.setState({
-      card: fromJS(card).toJS(),
-      elements: fromJS(card.elements).toJS(),
+      card: fromJS(card).toJS()
     })
   }
 
@@ -113,24 +108,10 @@
     const { cards } = this.props
     const { card } = this.state
 
-    let newcard = {}
+    let newcard = {eleType: 'button', label: 'button', verify: null, show: 'link', sqlType: '', Ot: 'requiredSgl', OpenType: 'prompt', icon: '', class: 'primary', intertype: 'system', execSuccess: 'grid', execError: 'never', popClose: 'never'}
     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.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)
@@ -141,76 +122,82 @@
     const { card } = this.state
 
     let _style = null
-    let options = ['height', 'background', 'border', 'padding', 'margin']
+    let options = ['height', 'background', 'border', 'padding', 'margin', 'shadow']
     _style = card.style ? fromJS(card.style).toJS() : {}
+
+    if (cards.type === 'carousel') {
+      options = ['background', 'border', 'padding', 'margin', 'shadow']
+    }
 
     MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style)
   }
 
-  settingSubmit = () => {
+  getSettingForms = () => {
+    const { cards } = this.props
+    const { setting } = this.state.card
+
+    if (cards.type !== 'carousel') {
+      return getTableSetting(setting, cards.columns)
+    } else {
+      return getCarouselSetting(setting, cards.subtype === 'propcard')
+    }
+  }
+
+  updateSetting = (res) => {
     const { card } = this.state
 
-    this.settingRef.handleConfirm().then(res => {
-      this.setState({
-        settingVisible: false,
-        card: {...card, setting: res}
-      })
+    if (res.appmenu) {
+      res.menu = res.appmenu
+    }
+    delete res.appmenu
 
-      this.props.updateElement({...card, setting: res})
-    })
+    let _card = {...card, setting: res}
+
+    this.setState({ card: _card })
+    this.props.updateElement(_card)
   }
 
   render() {
     const { cards } = this.props
-    const { card, elements, settingVisible, dict } = this.state
-    let _style = resetStyle(card.style)
+    const { card } = this.state
+
+    let _style = {...card.style}
+
+    if (cards.type === 'carousel') {
+      _style.height = cards.style.height
+    }
+    
+    _style = resetStyle(_style)
 
     return (
       <div className="ant-col ant-col-24">
         <div className="card-item" style={_style}>
-          <CardCellComponent cards={cards} cardCell={card} elements={elements} updateElement={this.updateCard}/>
+          <CardCellComponent cards={cards} cardCell={card} elements={card.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" title="缂栬緫" type="edit" onClick={() => this.setState({settingVisible: true})} />
+                <NormalForm title="鍗$墖璁剧疆" width={700} update={this.updateSetting} getForms={this.getSettingForms}>
+                  <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+                </NormalForm>
                 <CopyComponent type="cardcell" card={card}/>
                 <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
-                <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+                {cards.subtype !== 'datacard' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                   <div className="mk-popover-control">
                     <Icon className="plus" title="鍓嶇Щ" type="arrow-left" onClick={() => this.props.move(card, 'left')} />
                     <Icon className="close" title="鍚庣Щ" type="arrow-right" onClick={() => this.props.move(card, 'right')} />
                   </div>
                 } trigger="hover" getPopupContainer={() => document.getElementById(card.uuid + 'swap')}>
                   <Icon type="swap" id={card.uuid + 'swap'}/>
-                </Popover>
-                <Icon className="close" title="鍒犻櫎鍗$墖" type="delete" onClick={() => this.props.deleteElement(card)} />
+                </Popover> : null}
+                {cards.subtype !== 'datacard' ? <Icon className="close" title="鍒犻櫎鍗$墖" type="delete" onClick={() => this.props.deleteElement(card)} /> : null}
               </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>
     )
   }
diff --git a/src/menu/components/card/cardcomponent/pastecomponent/index.scss b/src/menu/components/card/cardsimplecomponent/index.scss
similarity index 100%
rename from src/menu/components/card/cardcomponent/pastecomponent/index.scss
rename to src/menu/components/card/cardsimplecomponent/index.scss
diff --git a/src/menu/components/card/cardsimplecomponent/options.jsx b/src/menu/components/card/cardsimplecomponent/options.jsx
new file mode 100644
index 0000000..c9affe0
--- /dev/null
+++ b/src/menu/components/card/cardsimplecomponent/options.jsx
@@ -0,0 +1,174 @@
+/**
+ * @description tablecard setting琛ㄥ崟閰嶇疆淇℃伅
+ */
+export function getTableSetting (setting, columns) {
+  let _columns = columns.map(item => ({value: item.field, label: item.label}))
+  _columns.push({value: '$Index', label: '搴忓彿锛堝墠绔級'})
+
+  const settingForm = [
+    {
+      type: 'radio',
+      field: 'condition',
+      label: '鏄剧ず鏉′欢',
+      initval: setting.condition || 'false',
+      tooltip: '褰撻�夋嫨鈥滄湁鈥濇椂锛屽彧鏈夌鍚堟潯浠剁殑鏁版嵁鎵嶄細灞曠ず銆�',
+      required: false,
+      options: [
+        {value: 'true', label: '鏈�'},
+        {value: 'false', label: '鏃�'},
+      ],
+      controlFields: [
+        {field: 'controlField', values: ['true']},
+        {field: 'controlType', values: ['true']},
+        {field: 'controlValue', values: ['true']},
+      ]
+    },
+    {
+      type: 'select',
+      field: 'controlField',
+      label: '鎺у埗瀛楁',
+      initval: setting.controlField || '',
+      required: true,
+      options: _columns
+    },
+    {
+      type: 'radio',
+      field: 'controlType',
+      label: '瀵规瘮鏂瑰紡',
+      initval: setting.controlType || '=',
+      required: true,
+      options: [
+        {value: '=', label: '='},
+        {value: '!=', label: '!='},
+        {value: '>', label: '>'},
+        {value: '<', label: '<'},
+      ]
+    },
+    {
+      type: 'text',
+      field: 'controlValue',
+      label: '瀵规瘮鍊�',
+      initval: setting.controlValue || '',
+      required: false
+    }
+  ]
+
+  return settingForm
+}
+
+/**
+ * @description carousel setting琛ㄥ崟閰嶇疆淇℃伅
+ */
+export function getCarouselSetting (setting, hasPrimaryKey) {
+  let appType = sessionStorage.getItem('appType')
+
+  let menulist = []
+  let appmenulist = []
+
+  if (appType) {
+    appmenulist = sessionStorage.getItem('appMenus')
+    if (appmenulist) {
+      try {
+        appmenulist = JSON.parse(appmenulist)
+      } catch {
+        appmenulist = []
+      }
+    } else {
+      appmenulist = []
+    }
+  } else {
+    menulist = sessionStorage.getItem('fstMenuList')
+    if (menulist) {
+      try {
+        menulist = JSON.parse(menulist)
+      } catch {
+        menulist = []
+      }
+    } else {
+      menulist = []
+    }
+  }
+
+  const cardSettingForm = [
+    {
+      type: 'text',
+      field: 'primaryId',
+      label: '涓婚敭鍊�',
+      initval: setting.primaryId || '',
+      tooltip: '鍗$墖鐐瑰嚮鏃讹紝鍚戝叾浠栫粍浠朵紶閫掔殑ID鍊笺��',
+      required: false,
+      forbid: !hasPrimaryKey
+    },
+    {
+      type: 'radio',
+      field: 'click',
+      label: '鐐瑰嚮浜嬩欢',
+      initval: setting.click || '',
+      required: false,
+      options: [
+        {value: '', label: '鏃�'},
+        {value: 'menu', label: '鑿滃崟'},
+        {value: 'link', label: '閾炬帴'},
+      ],
+      controlFields: [
+        {field: 'menu', values: ['menu']},
+        {field: 'appmenu', values: ['menu']},
+        {field: 'linkurl', values: ['link']},
+        {field: 'open', values: ['menu', 'link']},
+        {field: 'joint', values: ['menu', 'link']},
+      ]
+    },
+    {
+      type: 'cascader',
+      field: 'menu',
+      label: '鑿滃崟',
+      initval: setting.menu || [],
+      required: true,
+      options: menulist,
+      forbid: !!appType
+    },
+    {
+      type: 'select',
+      field: 'appmenu',
+      label: '鍏宠仈鑿滃崟',
+      initval: setting.menu || '',
+      required: true,
+      options: appmenulist,
+      forbid: !appType
+    },
+    {
+      type: 'textarea',
+      field: 'linkurl',
+      label: '閾炬帴',
+      initval: setting.linkurl || '',
+      required: true,
+      options: [],
+      span: 24
+    },
+    {
+      type: 'radio',
+      field: 'open',
+      label: '鎵撳紑鏂瑰紡',
+      initval: setting.open || 'blank',
+      required: false,
+      options: [
+        {value: 'blank', label: '鏂扮獥鍙�'},
+        {value: 'self', label: '褰撳墠绐楀彛'},
+      ],
+      forbid: appType !== 'pc'
+    },
+    {
+      type: 'radio',
+      field: 'joint',
+      label: '鍙傛暟鎷兼帴',
+      initval: setting.joint || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+    },
+  ]
+
+  return cardSettingForm
+}
\ No newline at end of file
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index eab3104..4e09ba6 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -8,18 +8,19 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.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 WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CardComponent = asyncComponent(() => import('../cardcomponent'))
 const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
-const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
+const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
 
@@ -253,48 +254,60 @@
     this.props.updateConfig(_card)
   }
 
-  addSearch = () => {
+  addSearch = (copy) => {
     const { card } = this.state
 
     let newcard = {}
-    newcard.uuid = Utils.getuuid()
-    newcard.focus = true
 
-    newcard.label = 'label'
-    newcard.type = 'select'
-    newcard.resourceType = '0'
-    newcard.options = []
-    newcard.setAll = 'false'
-    newcard.orderType = 'asc'
-    newcard.display = 'dropdown'
-    newcard.match = '='
+    if (copy) {
+      newcard = copy
+      newcard.focus = true
+    } else {
+      newcard.uuid = Utils.getuuid()
+      newcard.focus = true
+  
+      newcard.label = 'label'
+      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)
   }
 
-  addButton = () => {
+  addButton = (copy) => {
     const { card } = this.state
 
     let newcard = {}
-    newcard.uuid = Utils.getuuid()
-    newcard.focus = true
-    
-    newcard.label = 'label'
-    newcard.Ot = 'requiredSgl'
-    newcard.OpenType = 'pop'
-    newcard.icon = ''
-    newcard.class = 'green'
-    newcard.intertype = card.setting.interType || 'system'
-    newcard.innerFunc = card.setting.innerFunc || ''
-    newcard.sysInterface = card.setting.sysInterface || ''
-    newcard.outerFunc = card.setting.outerFunc || ''
-    newcard.interface = card.setting.interface || ''
-    newcard.execSuccess = 'grid'
-    newcard.execError = 'never'
-    newcard.verify = null
-    newcard.show = 'button'
-    newcard.style = {marginRight: '15px'}
+
+    if (copy) {
+      newcard = copy
+      newcard.focus = true
+    } else {
+      newcard.uuid = Utils.getuuid()
+      newcard.focus = true
+      
+      newcard.label = 'label'
+      newcard.Ot = 'requiredSgl'
+      newcard.OpenType = 'pop'
+      newcard.icon = ''
+      newcard.class = 'green'
+      newcard.intertype = card.setting.interType || 'system'
+      newcard.innerFunc = card.setting.innerFunc || ''
+      newcard.sysInterface = card.setting.sysInterface || ''
+      newcard.outerFunc = card.setting.outerFunc || ''
+      newcard.interface = card.setting.interface || ''
+      newcard.execSuccess = 'grid'
+      newcard.execError = 'never'
+      newcard.verify = null
+      newcard.show = 'button'
+      newcard.style = {marginRight: '15px'}
+    }
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鎸夐挳
     MKEmitter.emit('addButton', card.uuid, newcard)
@@ -383,26 +396,32 @@
     }
   }
 
-  addCard = () => {
+  addCard = (copy) => {
     let card = fromJS(this.state.card).toJS()
-    let height = card.subcards[0].style.height
-    if (height === 'auto') {
-      height = '100px'
-    }
+    let newcard = {}
 
-    let newcard = {
-      uuid: Utils.getuuid(),
-      $cardType: 'extendCard',
-      setting: { width: 6, type: 'simple', click: 'button'},
-      style: {
-        height,
-        borderWidth: '1px', borderColor: '#e8e8e8',
-        paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px',
-        marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
-      },
-      backStyle: {},
-      elements: [],
-      backElements: []
+    if (copy) { // 绮樿创
+      newcard = copy
+    } else {
+      let height = card.subcards[0].style.height
+      if (height === 'auto') {
+        height = '100px'
+      }
+  
+      newcard = {
+        uuid: Utils.getuuid(),
+        $cardType: 'extendCard',
+        setting: { width: 6, type: 'simple', click: 'button'},
+        style: {
+          height,
+          borderWidth: '1px', borderColor: '#e8e8e8',
+          paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px',
+          marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
+        },
+        backStyle: {},
+        elements: [],
+        backElements: []
+      }
     }
 
     card.subcards.push(newcard)
@@ -429,6 +448,147 @@
 
     this.setState({card})
     this.props.updateConfig(card)
+  }
+
+  getWrapForms = () => {
+    const { card } = this.state
+
+    return getWrapForm(card.wrap, card.subtype)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
+  pasteComponent = (res, resolve) => {
+    const { card, appType } = this.state
+
+    let type = res.copyType
+    delete res.copyType
+
+    if (type === 'cardcell') {
+      res.uuid = Utils.getuuid()
+      res.setting = res.setting || {}
+      res.$cardType = 'extendCard'
+      res.setting.width = res.setting.width || 6
+
+      let copyBtns = []
+      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
+
+      let elements = []
+      res.elements && res.elements.forEach(cell => {
+        if (cell.datatype === 'dynamic') {
+          cell.datatype = 'static'
+        }
+
+        if (cell.eleType !== 'button') {
+          cell.uuid = Utils.getuuid()
+          elements.push(cell)
+        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
+          return
+        } else {
+          let _uuid = Utils.getuuid()
+
+          if (cell.OpenType === 'popview') {
+            let _cell = fromJS(cell).toJS()
+            _cell.$originUuid = _cell.uuid
+            _cell.uuid = _uuid
+            copyBtns.push(_cell)
+          }
+
+          cell.uuid = _uuid
+          elements.push(cell)
+        }
+      })
+
+      res.elements = elements
+
+      let backElements = []
+
+      if (appType !== 'mob') {
+        res.backElements && res.backElements.forEach(cell => {
+          if (cell.datatype === 'dynamic') {
+            cell.datatype = 'static'
+          }
+
+          if (cell.eleType !== 'button') {
+            cell.uuid = Utils.getuuid()
+            backElements.push(cell)
+          } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
+            return
+          } else {
+            let _uuid = Utils.getuuid()
+  
+            if (cell.OpenType === 'popview') {
+              let _cell = fromJS(cell).toJS()
+              _cell.$originUuid = _cell.uuid
+              _cell.uuid = _uuid
+              copyBtns.push(_cell)
+            }
+  
+            cell.uuid = _uuid
+            backElements.push(cell)
+          }
+        })
+      }
+
+      res.backElements = backElements
+
+      if (copyBtns.length > 0) {
+        MKEmitter.emit('copyButtons', copyBtns)
+      }
+
+      resolve({status: true})
+
+      this.addCard(res)
+    } else if (type === 'search' || type === 'form') {
+      if (appType === 'mob') {
+        resolve({status: false, message: '绉诲姩绔暟鎹崱涓嶆敮鎸佹坊鍔犳悳绱㈡潯浠躲��'})
+      } else {
+        res.uuid = Utils.getuuid()
+        let keys = card.search.map(item => item.field.toLowerCase())
+  
+        if (type === 'form') {
+          if (['number', 'switch', 'textarea', 'fileupload', 'hint', 'color', 'funcvar'].includes(res.type)) {
+            res.type = 'text'
+          } else if (res.type === 'radio') {
+            res.type = 'select'
+          } else if (res.type === 'checkbox') {
+            res.type = 'multiselect'
+          } else if (res.type === 'datetime') {
+            res.type = 'date'
+          }
+        }
+  
+        if (res.field && keys.includes(res.field.toLowerCase())) {
+          resolve({status: false, message: '鎼滅储瀛楁宸插瓨鍦紒'})
+          return
+        }
+
+        resolve({status: true})
+
+        this.addSearch(res)
+      }
+    } else if (type === 'action') {
+      if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) {
+        resolve({status: false, message: '绉诲姩绔笉鏀寔姝ょ被鍨嬬殑鎸夐挳銆�'})
+      } else {
+        let _uuid = Utils.getuuid()
+  
+        if (res.OpenType === 'popview') {
+          let _cell = fromJS(res).toJS()
+          _cell.$originUuid = _cell.uuid
+          _cell.uuid = _uuid
+  
+          MKEmitter.emit('copyButtons', [_cell])
+        }
+
+        resolve({status: true})
+    
+        res.uuid = _uuid
+        this.addButton(res)
+      }
+    }
   }
 
   clickComponent = (e) => {
@@ -459,12 +619,14 @@
         <NormalHeader defaultshow="hidden" config={card} updateComponent={this.updateComponent}/>
         <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" />
-            {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} />
+            <Icon className="plus" title="娣诲姞鍗$墖" onClick={() => this.addCard()} 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" />
+            <NormalForm title="鏁版嵁鍗¤缃�" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="datacard" card={card}/>
-            <PasteComponent config={card} options={['action', 'search', 'form', 'cardcell']} updateConfig={this.updateComponent} />
+            <PasteComponent options={['action', 'search', 'form', 'cardcell']} updateConfig={this.pasteComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
             <UserComponent config={card}/>
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
new file mode 100644
index 0000000..84ef971
--- /dev/null
+++ b/src/menu/components/card/data-card/options.jsx
@@ -0,0 +1,163 @@
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (wrap, subtype) {
+  let appType = sessionStorage.getItem('appType')
+  let MenuType = ''
+
+  if (window.GLOB.customMenu.parentId === 'BillPrintTemp') {
+    MenuType = 'billPrint'
+  }
+
+  let roleList = sessionStorage.getItem('sysRoles')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const cardWrapForm = [
+    {
+      type: 'text',
+      field: 'title',
+      label: '鏍囬',
+      initval: wrap.title || '',
+      required: false
+    },
+    {
+      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: 'radio',
+      field: 'datatype',
+      label: '鏁版嵁鏉ユ簮',
+      initval: wrap.datatype || 'dynamic',
+      tooltip: '閫夋嫨闈欐�佸�硷紝鏃犻渶閰嶇疆鏁版嵁婧愩��',
+      required: false,
+      options: [
+        {value: 'dynamic', label: '鍔ㄦ��'},
+        {value: 'static', label: '闈欐��'},
+      ],
+      forbid: subtype !== 'propcard'
+    },
+    {
+      type: 'radio',
+      field: 'pagestyle',
+      label: '鍒嗛〉椋庢牸',
+      initval: wrap.pagestyle || 'page',
+      tooltip: '鏁版嵁婧愰�夋嫨鍒嗛〉鏃舵湁鏁堛��',
+      required: false,
+      options: [
+        {value: 'page', label: '椤电爜'},
+        {value: 'switch', label: '宸﹀彸鍒囨崲', forbid: appType === 'mob'},
+        {value: 'slide', label: '婊戝姩鍔犺浇', forbid: appType !== 'mob'},
+      ],
+      forbid: !(subtype === 'datacard' || (subtype === 'tablecard' && appType === 'mob'))
+    },
+    {
+      type: 'radio',
+      field: 'cardType',
+      label: '鏁版嵁閫夋嫨',
+      initval: wrap.cardType || '',
+      required: false,
+      options: [
+        {value: '', label: '涓嶅彲閫�'},
+        {value: 'radio', label: '鍗曢��'},
+        {value: 'checkbox', label: '澶氶��', forbid: subtype === 'propcard'},
+      ],
+      controlFields: [
+        {field: 'checkAll', values: ['checkbox']}
+      ],
+      forbid: subtype === 'tablecard'
+    },
+    {
+      type: 'radio',
+      field: 'checkAll',
+      label: '鍏ㄩ��',
+      initval: wrap.checkAll || 'hidden',
+      required: false,
+      options: [
+        {value: 'hidden', label: '闅愯棌'},
+        {value: 'show', label: '鏄剧ず'},
+      ],
+      forbid: subtype !== 'datacard' || appType !== 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'cardFloat',
+      label: '瀵归綈鏂瑰紡',
+      initval: wrap.cardFloat || 'left',
+      tooltip: '璁剧疆涓哄眳涓榻愭垨鍙冲榻愶紝鍙湪鍗$墖涓�1琛屾椂鏈夋晥銆�',
+      required: false,
+      options: [
+        {value: 'left', label: '宸﹀榻�'},
+        {value: 'center', label: '灞呬腑'},
+        {value: 'right', label: '鍙冲榻�'},
+      ],
+      forbid: subtype === 'tablecard'
+    },
+    {
+      type: 'radio',
+      field: 'scale',
+      label: '鏀惧ぇ鏁堟灉',
+      initval: wrap.scale || 'false',
+      tooltip: '榧犳爣鎮诞浜庡崱鐗囦笂鏂规椂锛屽崱鐗囨斁澶�1.05鍊嶃��',
+      required: false,
+      options: [
+        {value: 'false', label: '鏃�'},
+        {value: 'true', label: '鏈�'},
+      ],
+      forbid: subtype === 'tablecard' || appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'printType',
+      label: '缁勪欢绫诲瀷',
+      initval: wrap.printType || 'content',
+      tooltip: '閫夋嫨绫诲瀷涓恒�婇〉鐪�/椤佃剼銆嬫椂锛屾墦鍗扮殑姣忛〉閲岄兘浼氬甫鏈夎缁勪欢銆�',
+      required: false,
+      options: [
+        {value: 'content', label: '鍐呭'},
+        {value: 'headerOrfooter', label: '椤电湁/椤佃剼'},
+      ],
+      forbid: subtype !== 'propcard' || MenuType !== 'billPrint'
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: wrap.blacklist || [],
+      required: false,
+      options: roleList
+    },
+  ]
+
+  return cardWrapForm.map(item => {
+    if (['pagestyle', 'cardType'].includes(item.field)) {
+      item.options = item.options.filter(option => !option.forbid)
+    }
+
+    return item
+  })
+} 
\ No newline at end of file
diff --git a/src/menu/components/card/data-card/wrapsetting/index.jsx b/src/menu/components/card/data-card/wrapsetting/index.jsx
deleted file mode 100644
index 8877617..0000000
--- a/src/menu/components/card/data-card/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 CardWrapSetting 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" title="缂栬緫" onClick={() => this.editDataSource()} />
-        <Modal
-          wrapClassName="popview-modal"
-          title={config.type === 'table' ? '琛ㄦ牸璁剧疆' : '鍗$墖璁剧疆'}
-          visible={visible}
-          width={800}
-          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 CardWrapSetting
\ No newline at end of file
diff --git a/src/menu/components/card/data-card/wrapsetting/index.scss b/src/menu/components/card/data-card/wrapsetting/index.scss
deleted file mode 100644
index 04372e6..0000000
--- a/src/menu/components/card/data-card/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/card/data-card/wrapsetting/settingform/index.jsx b/src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
deleted file mode 100644
index d1c8eb0..0000000
--- a/src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
+++ /dev/null
@@ -1,263 +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: [],
-    appType: sessionStorage.getItem('appType'),
-    cardType: this.props.wrap.cardType,
-    MenuType: ''
-  }
-
-  UNSAFE_componentWillMount () {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch {
-        roleList = []
-      }
-    } else {
-      roleList = []
-    }
-
-    let MenuType = ''
-
-    if (window.GLOB.customMenu && window.GLOB.customMenu.parentId === 'BillPrintTemp') {
-      MenuType = 'billPrint'
-    }
-
-    this.setState({roleList, MenuType})
-  }
-
-  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, MenuType, appType, cardType } = 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="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负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>
-            {config.subtype === 'propcard' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="閫夋嫨闈欐�佸�硷紝鏃犻渶閰嶇疆鏁版嵁婧愩��">
-                  <Icon type="question-circle" />
-                  鏁版嵁鏉ユ簮
-                </Tooltip>
-              }>
-                {getFieldDecorator('datatype', {
-                  initialValue: wrap.datatype || 'dynamic'
-                })(
-                  <Radio.Group>
-                    <Radio value="dynamic">鍔ㄦ��</Radio>
-                    <Radio value="static">闈欐��</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {config.subtype === 'datacard' || (config.subtype === 'tablecard' && appType === 'mob') ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鏁版嵁婧愪腑閫夋嫨鍒嗛〉鏃舵湁鏁堛��">
-                  <Icon type="question-circle" />
-                  鍒嗛〉椋庢牸
-                </Tooltip>
-              }>
-                {getFieldDecorator('pagestyle', {
-                  initialValue: wrap.pagestyle || 'page'
-                })(
-                  <Radio.Group>
-                    <Radio value="page">椤电爜</Radio>
-                    {appType !== 'mob' ? <Radio value="switch">宸﹀彸鍒囨崲</Radio> : null}
-                    {appType === 'mob' ? <Radio value="slide">婊戝姩鍔犺浇</Radio> : null}
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {config.subtype !== 'tablecard' ? <Col span={12}>
-              <Form.Item label="鍗$墖灞炴��">
-                {getFieldDecorator('cardType', {
-                  initialValue: wrap.cardType || ''
-                })(
-                  <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({cardType: e.target.value})}>
-                    <Radio key="" value=""> 涓嶅彲閫� </Radio>
-                    <Radio key="radio" value={'radio'}> 鍗曢�� </Radio>
-                    {config.subtype !== 'propcard' ? <Radio key="checkbox" value={'checkbox'}> 澶氶�� </Radio> : null}
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {config.subtype === 'datacard' && appType === 'mob' && cardType === 'checkbox' ? <Col span={12}>
-              <Form.Item label="鍏ㄩ��">
-                {getFieldDecorator('checkAll', {
-                  initialValue: wrap.checkAll || 'hidden'
-                })(
-                  <Radio.Group>
-                    <Radio key="hidden" value="hidden"> 闅愯棌 </Radio>
-                    <Radio key="show" value="show"> 鏄剧ず </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {config.subtype !== 'tablecard' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="璁剧疆涓哄眳涓榻愭垨鍙冲榻愶紝鍙湪鍗$墖涓�1琛屾椂鏈夋晥銆�">
-                  <Icon type="question-circle" />
-                  鍗$墖鎺掑垪
-                </Tooltip>
-              }>
-                {getFieldDecorator('cardFloat', {
-                  initialValue: wrap.cardFloat || 'left'
-                })(
-                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
-                    <Radio key="left" value="left"> 宸﹀榻� </Radio>
-                    <Radio key="center" value="center"> 灞呬腑 </Radio>
-                    <Radio key="right" value="right"> 鍙冲榻� </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {config.subtype !== 'tablecard' && appType !== 'mob' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="榧犳爣鎮诞浜庡崱鐗囦笂鏂规椂锛屽崱鐗囨斁澶�1.05鍊嶃��">
-                  <Icon type="question-circle" />
-                  鍗$墖鏀惧ぇ
-                </Tooltip>
-              }>
-                {getFieldDecorator('scale', {
-                  initialValue: wrap.scale || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio key="false" value="false"> 鍚� </Radio>
-                    <Radio key="true" value="true"> 鏄� </Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {config.subtype === 'propcard' && MenuType === 'billPrint' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="閫夋嫨绫诲瀷涓恒�婇〉鐪�/椤佃剼銆嬫椂锛屾墦鍗扮殑姣忛〉閲岄兘浼氬甫鏈夎缁勪欢銆�">
-                  <Icon type="question-circle" />
-                  缁勪欢绫诲瀷
-                </Tooltip>
-              }>
-                {getFieldDecorator('printType', {
-                  initialValue: wrap.printType || 'content'
-                })(
-                  <Radio.Group>
-                    <Radio value="content">鍐呭</Radio>
-                    <Radio value="headerOrfooter">椤电湁/椤佃剼</Radio>
-                  </Radio.Group>
-                )}
-              </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/card/data-card/wrapsetting/settingform/index.scss b/src/menu/components/card/data-card/wrapsetting/settingform/index.scss
deleted file mode 100644
index 159130b..0000000
--- a/src/menu/components/card/data-card/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/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index 82de7bd..b7ab1ac 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -8,15 +8,16 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
+import getWrapForm from '../data-card/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 WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CardComponent = asyncComponent(() => import('../cardcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
+const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
@@ -255,33 +256,38 @@
     this.props.updateConfig(_card)
   }
 
-  addCard = () => {
+  addCard = (copy) => {
     let card = fromJS(this.state.card).toJS()
+    let newcard = {}
 
-    let newcard = {
-      uuid: Utils.getuuid(),
-      setting: { width: 6, type: 'simple'},
-      style: {
-        borderWidth: '1px', borderColor: '#e8e8e8',
-        paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px',
-        marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
-      },
-      backStyle: {},
-      elements: [],
-      backElements: []
-    }
-
-    if (card.subcards.length > 0) {
-      newcard = fromJS(card.subcards.slice(-1)[0]).toJS()
-      newcard.uuid = Utils.getuuid()
-      newcard.elements = newcard.elements.map(elem => {
-        elem.uuid = Utils.getuuid()
-        return elem
-      })
-      newcard.backElements = newcard.backElements.map(elem => {
-        elem.uuid = Utils.getuuid()
-        return elem
-      })
+    if (copy) { // 绮樿创
+      newcard = copy
+    } else {
+      newcard = {
+        uuid: Utils.getuuid(),
+        setting: { width: 6, type: 'simple'},
+        style: {
+          borderWidth: '1px', borderColor: '#e8e8e8',
+          paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px',
+          marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
+        },
+        backStyle: {},
+        elements: [],
+        backElements: []
+      }
+  
+      if (card.subcards.length > 0) {
+        newcard = fromJS(card.subcards.slice(-1)[0]).toJS()
+        newcard.uuid = Utils.getuuid()
+        newcard.elements = newcard.elements.map(elem => {
+          elem.uuid = Utils.getuuid()
+          return elem
+        })
+        newcard.backElements = newcard.backElements.map(elem => {
+          elem.uuid = Utils.getuuid()
+          return elem
+        })
+      }
     }
 
     card.subcards.push(newcard)
@@ -359,6 +365,89 @@
     this.props.updateConfig(card)
   }
 
+  pasteComponent = (res, resolve) => {
+    const { appType } = this.state
+
+    delete res.copyType
+    delete res.$cardType
+
+    res.uuid = Utils.getuuid()
+    res.setting = res.setting || {}
+    res.setting.width = res.setting.width || 6
+
+    let copyBtns = []
+    let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
+
+    let elements = []
+    res.elements && res.elements.forEach(cell => {
+      if (cell.eleType !== 'button') {
+        cell.uuid = Utils.getuuid()
+        elements.push(cell)
+      } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
+        return
+      } else {
+        let _uuid = Utils.getuuid()
+
+        if (cell.OpenType === 'popview') {
+          let _cell = fromJS(cell).toJS()
+          _cell.$originUuid = _cell.uuid
+          _cell.uuid = _uuid
+          copyBtns.push(_cell)
+        }
+
+        cell.uuid = _uuid
+        elements.push(cell)
+      }
+    })
+
+    res.elements = elements
+
+    let backElements = []
+
+    if (appType !== 'mob') {
+      res.backElements && res.backElements.forEach(cell => {
+        if (cell.eleType !== 'button') {
+          cell.uuid = Utils.getuuid()
+          backElements.push(cell)
+        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
+          return
+        } else {
+          let _uuid = Utils.getuuid()
+
+          if (cell.OpenType === 'popview') {
+            let _cell = fromJS(cell).toJS()
+            _cell.$originUuid = _cell.uuid
+            _cell.uuid = _uuid
+            copyBtns.push(_cell)
+          }
+
+          cell.uuid = _uuid
+          backElements.push(cell)
+        }
+      })
+    }
+
+    res.backElements = backElements
+
+    if (copyBtns.length > 0) {
+      MKEmitter.emit('copyButtons', copyBtns)
+    }
+
+    resolve({status: true})
+
+    this.addCard(res)
+  }
+
+  getWrapForms = () => {
+    const { card } = this.state
+
+    return getWrapForm(card.wrap, card.subtype)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -388,10 +477,12 @@
         <NormalHeader defaultshow="hidden" config={card} updateComponent={this.updateComponent}/>
         <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" />
-            <WrapComponent config={card} updateConfig={this.updateComponent} />
+            <Icon className="plus" title="娣诲姞鍗$墖" onClick={() => this.addCard()} type="plus" />
+            <NormalForm title="灞炴�у崱璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="propcard" card={card}/>
-            <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
+            <PasteComponent options={['cardcell']} updateConfig={this.pasteComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
diff --git a/src/menu/components/card/table-card/cardcomponent/index.scss b/src/menu/components/card/table-card/cardcomponent/index.scss
deleted file mode 100644
index e69de29..0000000
--- a/src/menu/components/card/table-card/cardcomponent/index.scss
+++ /dev/null
diff --git a/src/menu/components/card/table-card/cardcomponent/settingform/index.jsx b/src/menu/components/card/table-card/cardcomponent/settingform/index.jsx
deleted file mode 100644
index c4054ef..0000000
--- a/src/menu/components/card/table-card/cardcomponent/settingform/index.jsx
+++ /dev/null
@@ -1,132 +0,0 @@
-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.Option key={'index'} value={'$Index'}>搴忓彿锛堝墠绔級</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/card/table-card/cardcomponent/settingform/index.scss b/src/menu/components/card/table-card/cardcomponent/settingform/index.scss
deleted file mode 100644
index 159130b..0000000
--- a/src/menu/components/card/table-card/cardcomponent/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/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index 5f34e5c..88eaaf7 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -8,16 +8,17 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
+import getWrapForm from '../data-card/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 WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting'))
-const CardComponent = asyncComponent(() => import('./cardcomponent'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
+const CardSimpleComponent = asyncComponent(() => import('../cardsimplecomponent'))
 const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
+const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -227,25 +228,30 @@
     this.props.updateConfig(_card)
   }
 
-  addCard = () => {
+  addCard = (copy) => {
     let card = fromJS(this.state.card).toJS()
+    let newcard = {}
 
-    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.slice(-1)[0]).toJS()
-      newcard.uuid = Utils.getuuid()
-      newcard.elements = newcard.elements.map(elem => {
-        elem.uuid = Utils.getuuid()
-        return elem
-      })
+    if (copy) { // 绮樿创
+      newcard = copy
+    } else {
+      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.slice(-1)[0]).toJS()
+        newcard.uuid = Utils.getuuid()
+        newcard.elements = newcard.elements.map(elem => {
+          elem.uuid = Utils.getuuid()
+          return elem
+        })
+      }
     }
 
     card.subcards.push(newcard)
@@ -254,22 +260,28 @@
     this.props.updateConfig(card)
   }
 
-  addSearch = () => {
+  addSearch = (copy) => {
     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 = '='
+    if (copy) {
+      newcard = copy
+      newcard.focus = true
+    } else {
+      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)
@@ -342,6 +354,95 @@
     this.props.updateConfig(card)
   }
 
+  getWrapForms = () => {
+    const { card } = this.state
+
+    return getWrapForm(card.wrap, card.subtype)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
+  pasteComponent = (res, resolve) => {
+    const { card, appType } = this.state
+
+    let type = res.copyType
+    delete res.copyType
+
+    if (type === 'cardcell') {
+      res.uuid = Utils.getuuid()
+      res.setting = res.setting || {}
+      res.setting.width = res.setting.width || 6
+
+      let copyBtns = []
+      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
+
+      let elements = []
+      res.elements && res.elements.forEach(cell => {
+        if (cell.eleType !== 'button') {
+          cell.uuid = Utils.getuuid()
+          elements.push(cell)
+        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
+          return
+        } else {
+          let _uuid = Utils.getuuid()
+
+          if (cell.OpenType === 'popview') {
+            let _cell = fromJS(cell).toJS()
+            _cell.$originUuid = _cell.uuid
+            _cell.uuid = _uuid
+            copyBtns.push(_cell)
+          }
+
+          cell.uuid = _uuid
+          elements.push(cell)
+        }
+      })
+
+      res.elements = elements
+
+      delete res.$cardType
+      delete res.backElements
+
+      if (copyBtns.length > 0) {
+        MKEmitter.emit('copyButtons', copyBtns)
+      }
+
+      resolve({status: true})
+
+      this.addCard(res)
+    } else if (type === 'search' || type === 'form') {
+      if (appType === 'mob') {
+        resolve({status: false, message: '绉诲姩绔暟鎹崱涓嶆敮鎸佹坊鍔犳悳绱㈡潯浠躲��'})
+      } else {
+        res.uuid = Utils.getuuid()
+        let keys = card.search.map(item => item.field.toLowerCase())
+  
+        if (type === 'form') {
+          if (['number', 'switch', 'textarea', 'fileupload', 'hint', 'color', 'funcvar'].includes(res.type)) {
+            res.type = 'text'
+          } else if (res.type === 'radio') {
+            res.type = 'select'
+          } else if (res.type === 'checkbox') {
+            res.type = 'multiselect'
+          } else if (res.type === 'datetime') {
+            res.type = 'date'
+          }
+        }
+  
+        if (res.field && keys.includes(res.field.toLowerCase())) {
+          resolve({status: false, message: '鎼滅储瀛楁宸插瓨鍦紒'})
+          return
+        }
+
+        resolve({status: true})
+
+        this.addSearch(res)
+      }
+    }
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -358,11 +459,13 @@
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <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" />
-            {appType !== 'mob' ? <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" /> : null}
-            <WrapComponent config={card} updateConfig={this.updateComponent} />
+            <Icon className="plus" title="娣诲姞鍗$墖" onClick={() => this.addCard()} type="plus" />
+            {appType !== 'mob' ? <Icon className="plus" title="娣诲姞鎼滅储" onClick={() => this.addSearch()} type="plus-circle" /> : null}
+            <NormalForm title="琛ㄦ牸璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
             <CopyComponent type="tablecard" card={card}/>
-            <PasteComponent config={card} options={['cardcell', 'search', 'form']} updateConfig={this.updateComponent} />
+            <PasteComponent options={['cardcell', 'search', 'form']} updateConfig={this.pasteComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
             <UserComponent config={card}/>
@@ -373,7 +476,7 @@
           <Icon type="tool" />
         </Popover>
         <div style={{minHeight: 'calc(100% - 90px)'}}>
-          {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} move={this.move} deleteElement={this.deleteCard}/>))}
+          {card.subcards.map(subcard => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} move={this.move} deleteElement={this.deleteCard}/>))}
         </div>
         {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType !== 'mob' ? <Pagination size="small" total={50} /> : null}
         {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType === 'mob' ? <MobPagination /> : null}
diff --git a/src/menu/components/carousel/cardcomponent/index.jsx b/src/menu/components/carousel/cardcomponent/index.jsx
deleted file mode 100644
index 51cb8e0..0000000
--- a/src/menu/components/carousel/cardcomponent/index.jsx
+++ /dev/null
@@ -1,227 +0,0 @@
-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 asyncIconComponent from '@/utils/asyncIconComponent'
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import SettingForm from './settingform'
-import { resetStyle } from '@/utils/utils-custom.js'
-import Utils from '@/utils/utils.js'
-import MKEmitter from '@/utils/events.js'
-import './index.scss'
-
-const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
-const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-
-class CardBoxComponent extends Component {
-  static propTpyes = {
-    cards: PropTypes.object,         // 鍗$墖琛岄厤缃俊鎭�
-    card: PropTypes.object,          // 鍗$墖閰嶇疆淇℃伅
-    move: PropTypes.func,            // 鍗$墖绉诲姩
-    deleteElement: PropTypes.func,   // 鍗$墖鍒犻櫎
-    updateElement: PropTypes.func    // 鑿滃崟閰嶇疆鏇存柊
-  }
-
-  state = {
-    dict: sessionStorage.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) {
-    const { cards } = this.props
-    
-    return !is(fromJS(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.height = 1
-
-    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-    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.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 options = ['background', 'border', 'padding', 'margin', 'shadow']
-
-    MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, fromJS(card.style).toJS())
-  }
-
-  settingSubmit = () => {
-    const { card } = this.state
-
-    this.settingRef.handleConfirm().then(res => {
-      this.setState({
-        settingVisible: false,
-        card: {...card, setting: res}
-      })
-
-      this.props.updateElement({...card, setting: res})
-    })
-  }
-
-  clickComponent = (e) => {
-    if ((sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'propcard') && this.props.cards.subtype === 'propcard') {
-      e.stopPropagation()
-      MKEmitter.emit('clickComponent', this.state.card, this.props.cards, 'propcard')
-    }
-  }
-
-  render() {
-    const { cards } = this.props
-    const { card, elements, settingVisible, dict } = this.state
-
-    let _style = {...card.style}
-
-    _style.height = cards.style.height
-    _style = resetStyle(_style)
-
-    return (
-      <div className="card-item" style={_style} onClick={this.clickComponent} id={card.uuid}>
-        <CardCellComponent cards={cards} cardCell={card} side="front" 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" title="缂栬緫" type="edit" onClick={() => this.setState({settingVisible: true})} />
-              <CopyComponent type="cardcell" card={card}/>
-              <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
-              {cards.subtype === 'propcard' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-                <div className="mk-popover-control">
-                  <Icon className="plus" title="宸︾Щ" type="arrow-left" onClick={() => this.props.move(card, 'left')} />
-                  <Icon className="close" title="鍙崇Щ" type="arrow-right" onClick={() => this.props.move(card, 'right')} />
-                </div>
-              } trigger="hover" getPopupContainer={() => document.getElementById(card.uuid + 'swap')}>
-                <Icon type="swap" id={card.uuid + 'swap'}/>
-              </Popover> : null}
-              {cards.subtype === 'propcard' ? <Icon className="close" title="鍒犻櫎鍗$墖" type="delete" onClick={() => this.props.deleteElement(card)} /> : null}
-            </div>
-          } trigger="hover">
-            <Icon type="tool" />
-          </Popover>
-        </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/carousel/cardcomponent/index.scss b/src/menu/components/carousel/cardcomponent/index.scss
deleted file mode 100644
index e69de29..0000000
--- a/src/menu/components/carousel/cardcomponent/index.scss
+++ /dev/null
diff --git a/src/menu/components/carousel/cardcomponent/settingform/index.jsx b/src/menu/components/carousel/cardcomponent/settingform/index.jsx
deleted file mode 100644
index d8046cc..0000000
--- a/src/menu/components/carousel/cardcomponent/settingform/index.jsx
+++ /dev/null
@@ -1,194 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { Form, Row, Col, Radio, Tooltip, Icon, Input, Cascader, Select } from 'antd'
-
-import './index.scss'
-
-const { TextArea } = Input
-
-class SettingForm extends Component {
-  static propTpyes = {
-    dict: PropTypes.object,      // 瀛楀吀椤�
-    cards: PropTypes.object,     // 鍗$墖闆�
-    setting: PropTypes.object,   // 鏁版嵁婧愰厤缃�
-    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
-  }
-
-  state = {
-    type: this.props.setting.type || 'simple',
-    click: this.props.setting.click || '',
-    isApp: sessionStorage.getItem('appType') === 'pc',
-    menulist: []
-  }
-
-  UNSAFE_componentWillMount() {
-    const { isApp } = this.state
-    let menulist = null
-
-    if (isApp) {
-      menulist = sessionStorage.getItem('appMenus')
-    } else {
-      menulist = sessionStorage.getItem('fstMenuList')
-    }
-
-    if (menulist) {
-      try {
-        menulist = JSON.parse(menulist)
-      } catch {
-        menulist = []
-      }
-    } else {
-      menulist = []
-    }
-
-    this.setState({menulist})
-  }
-
-  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 { click, menulist, isApp } = 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}>
-            {cards.subtype === 'propcard' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鍗$墖鐐瑰嚮鏃讹紝鍚戝叾浠栫粍浠朵紶閫掔殑BID鍊笺��">
-                  <Icon type="question-circle" />
-                  涓婚敭鍊�
-                </Tooltip>
-              }>
-                {getFieldDecorator('primaryId', {
-                  initialValue: setting.primaryId || ''
-                })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>)}
-              </Form.Item>
-            </Col> : null}
-            <Col span={12}>
-              <Form.Item label="鐐瑰嚮浜嬩欢">
-                {getFieldDecorator('click', {
-                  initialValue: click
-                })(
-                  <Radio.Group onChange={(e) => this.setState({click: e.target.value})}>
-                    <Radio value="">鏃�</Radio>
-                    <Radio value="menu">鑿滃崟</Radio>
-                    <Radio value="link">閾炬帴</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            {!isApp && click === 'menu' ? <Col span={12}>
-              <Form.Item label="鑿滃崟">
-                {getFieldDecorator('menu', {
-                  initialValue: setting.menu || [],
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.select'] + '鑿滃崟!'
-                    }
-                  ]
-                })(
-                  <Cascader options={menulist} placeholder=""/>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {isApp && click === 'menu' ? <Col span={12}>
-              <Form.Item label="鍏宠仈鑿滃崟">
-                {getFieldDecorator('menu', {
-                  initialValue: setting.menu || '',
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.select'] + '鍏宠仈鑿滃崟!'
-                    }
-                  ]
-                })(
-                  <Select
-                    showSearch
-                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  >
-                    {menulist.map(option =>
-                      <Select.Option key={option.MenuID} value={option.MenuID}>{option.MenuName}</Select.Option>
-                    )}
-                  </Select>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {click === 'link' ? <Col span={24} className="textarea">
-              <Form.Item label="閾炬帴">
-                {getFieldDecorator('linkurl', {
-                  initialValue: setting.linkurl || '',
-                  rules: [
-                    {
-                      required: true,
-                      message: this.props.dict['form.required.input'] + '閾炬帴!'
-                    }
-                  ]
-                })( <TextArea rows={2}/> )}
-              </Form.Item>
-            </Col> : null}
-            {isApp ? <Col span={12}>
-              <Form.Item label="鎵撳紑鏂瑰紡">
-                {getFieldDecorator('open', {
-                  initialValue: setting.open || 'blank'
-                })(
-                  <Radio.Group>
-                    <Radio value="blank">鏂扮獥鍙�</Radio>
-                    <Radio value="self">褰撳墠绐楀彛</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {click !== '' ? <Col span={12}>
-              <Form.Item label="鍙傛暟鎷兼帴">
-                {getFieldDecorator('joint', {
-                  initialValue: setting.joint || 'true'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄�</Radio>
-                    <Radio value="false">鍚�</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-          </Row>
-        </Form>
-      </div>
-    )
-  }
-}
-
-export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/carousel/cardcomponent/settingform/index.scss b/src/menu/components/carousel/cardcomponent/settingform/index.scss
deleted file mode 100644
index 159130b..0000000
--- a/src/menu/components/carousel/cardcomponent/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/carousel/data-card/index.jsx b/src/menu/components/carousel/data-card/index.jsx
index 75d24c5..2144877 100644
--- a/src/menu/components/carousel/data-card/index.jsx
+++ b/src/menu/components/carousel/data-card/index.jsx
@@ -8,13 +8,14 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.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 WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
-const CardComponent = asyncComponent(() => import('../cardcomponent'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
+const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
@@ -250,6 +251,16 @@
     }
   }
 
+  getWrapForms = () => {
+    const { card } = this.state
+
+    return getWrapForm(card.wrap, card.subtype)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -265,7 +276,9 @@
       <div className="menu-data-carousel-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
         <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="datacard" card={card}/>
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors"/>
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/>
@@ -276,7 +289,7 @@
         } trigger="hover">
           <Icon type="tool"/>
         </Popover>
-        <CardComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/>
+        <CardSimpleComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/>
       </div>
     )
   }
diff --git a/src/menu/components/carousel/data-card/options.jsx b/src/menu/components/carousel/data-card/options.jsx
new file mode 100644
index 0000000..6631041
--- /dev/null
+++ b/src/menu/components/carousel/data-card/options.jsx
@@ -0,0 +1,133 @@
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (wrap, subtype) {
+  let appType = sessionStorage.getItem('appType')
+  let roleList = sessionStorage.getItem('sysRoles')
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  const cardWrapForm = [
+    {
+      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: 'radio',
+      field: 'datatype',
+      label: '鏁版嵁鏉ユ簮',
+      initval: wrap.datatype || 'dynamic',
+      tooltip: '閫夋嫨闈欐�佸�硷紝鏃犻渶閰嶇疆鏁版嵁婧愩��',
+      required: false,
+      options: [
+        {value: 'dynamic', label: '鍔ㄦ��'},
+        {value: 'static', label: '闈欐��'},
+      ],
+      forbid: subtype !== 'propcard'
+    },
+    {
+      type: 'radio',
+      field: 'autoplay',
+      label: '鑷姩鍒囨崲',
+      initval: wrap.autoplay || 'false',
+      required: false,
+      options: [
+        {value: 'false', label: '鍚�'},
+        {value: 'true', label: '鏄�'},
+      ]
+    },
+    {
+      type: 'number',
+      field: 'speed',
+      label: '鏃堕棿闂撮殧',
+      initval: wrap.speed || 3,
+      tooltip: '浣跨敤鑷姩鍒囨崲鏃舵湁鏁堬紝榛樿涓�3绉�',
+      min: 1,
+      max: 100,
+      precision: 0,
+      required: false
+    },
+    {
+      type: 'radio',
+      field: 'dots',
+      label: '鎸囩ず鐐�',
+      initval: wrap.dots || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'vertical',
+      label: '鍨傜洿鏄剧ず',
+      initval: wrap.vertical || 'false',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'dotPosition',
+      label: '鎸囩ず鐐逛綅缃�',
+      initval: wrap.dotPosition || 'bottom',
+      required: false,
+      options: [
+        {value: 'top', label: '涓�'},
+        {value: 'bottom', label: '涓�'},
+        {value: 'left', label: '宸�'},
+        {value: 'right', label: '鍙�'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'effect',
+      label: '鍔ㄧ敾鏁堟灉',
+      initval: wrap.effect || 'scrollx',
+      required: false,
+      options: [
+        {value: 'scrollx', label: '鍒囨崲'},
+        {value: 'fade', label: '娓愭樉'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: wrap.blacklist || [],
+      required: false,
+      options: roleList
+    },
+  ]
+
+  return cardWrapForm
+} 
\ No newline at end of file
diff --git a/src/menu/components/carousel/data-card/wrapsetting/index.jsx b/src/menu/components/carousel/data-card/wrapsetting/index.jsx
deleted file mode 100644
index 7b28116..0000000
--- a/src/menu/components/carousel/data-card/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" title="缂栬緫" onClick={() => this.editDataSource()} />
-        <Modal
-          wrapClassName="popview-modal"
-          title="鍗$墖璁剧疆"
-          visible={visible}
-          width={800}
-          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/carousel/data-card/wrapsetting/index.scss b/src/menu/components/carousel/data-card/wrapsetting/index.scss
deleted file mode 100644
index 04372e6..0000000
--- a/src/menu/components/carousel/data-card/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/carousel/data-card/wrapsetting/settingform/index.jsx b/src/menu/components/carousel/data-card/wrapsetting/settingform/index.jsx
deleted file mode 100644
index 21fec41..0000000
--- a/src/menu/components/carousel/data-card/wrapsetting/settingform/index.jsx
+++ /dev/null
@@ -1,227 +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 = {
-    appType: sessionStorage.getItem('appType'),
-    roleList: []
-  }
-
-  UNSAFE_componentWillMount () {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch {
-        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={
-                <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>
-            {config.subtype === 'propcard' ? <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="閫夋嫨闈欐�佸�硷紝鏃犻渶閰嶇疆鏁版嵁婧愩��">
-                  <Icon type="question-circle" />
-                  鏁版嵁鏉ユ簮
-                </Tooltip>
-              }>
-                {getFieldDecorator('datatype', {
-                  initialValue: wrap.datatype || 'dynamic'
-                })(
-                  <Radio.Group>
-                    <Radio value="dynamic">鍔ㄦ��</Radio>
-                    <Radio value="static">闈欐��</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            <Col span={12}>
-              <Form.Item label="鑷姩鍒囨崲">
-                {getFieldDecorator('autoplay', {
-                  initialValue: wrap.autoplay || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio value="false">鍚�</Radio>
-                    <Radio value="true">鏄�</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="浣跨敤鑷姩鍒囨崲鏃舵湁鏁堬紝榛樿涓�3绉掋��">
-                  <Icon type="question-circle" />
-                  鏃堕棿闂撮殧
-                </Tooltip>
-              }>
-                {getFieldDecorator('speed', {
-                  initialValue: wrap.speed || 3
-                })(<InputNumber min={1} max={100} precision={0} onPressEnter={this.handleSubmit} />)}
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item label="鎸囩ず鐐�">
-                {getFieldDecorator('dots', {
-                  initialValue: wrap.dots || 'true'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄剧ず</Radio>
-                    <Radio value="false">闅愯棌</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col>
-            {appType === 'mob' ? <Col span={12}>
-              <Form.Item label="鍨傜洿鏄剧ず">
-                {getFieldDecorator('vertical', {
-                  initialValue: wrap.vertical || 'false'
-                })(
-                  <Radio.Group>
-                    <Radio value="true">鏄�</Radio>
-                    <Radio value="false">鍚�</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label="鎸囩ず鐐逛綅缃�">
-                {getFieldDecorator('dotPosition', {
-                  initialValue: wrap.dotPosition || 'bottom'
-                })(
-                  <Radio.Group>
-                    <Radio value="top">涓�</Radio>
-                    <Radio value="bottom">涓�</Radio>
-                    <Radio value="left">宸�</Radio>
-                    <Radio value="right">鍙�</Radio>
-                  </Radio.Group>
-                )}
-              </Form.Item>
-            </Col> : null}
-            {appType !== 'mob' ? <Col span={12}>
-              <Form.Item label="鍔ㄧ敾鏁堟灉">
-                {getFieldDecorator('effect', {
-                  initialValue: wrap.effect || 'scrollx'
-                })(
-                  <Radio.Group>
-                    <Radio value="scrollx">鍒囨崲</Radio>
-                    <Radio value="fade">娓愭樉</Radio>
-                  </Radio.Group>
-                )}
-              </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/carousel/data-card/wrapsetting/settingform/index.scss b/src/menu/components/carousel/data-card/wrapsetting/settingform/index.scss
deleted file mode 100644
index 159130b..0000000
--- a/src/menu/components/carousel/data-card/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/carousel/prop-card/index.jsx b/src/menu/components/carousel/prop-card/index.jsx
index 6459a3d..dd686fb 100644
--- a/src/menu/components/carousel/prop-card/index.jsx
+++ b/src/menu/components/carousel/prop-card/index.jsx
@@ -8,13 +8,14 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
+import getWrapForm from '../data-card/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 WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting'))
-const CardComponent = asyncComponent(() => import('../cardcomponent'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
+const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
@@ -327,6 +328,16 @@
     this.props.updateConfig(card)
   }
 
+  getWrapForms = () => {
+    const { card } = this.state
+
+    return getWrapForm(card.wrap, card.subtype)
+  }
+
+  updateWrap = (res) => {
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
       e.stopPropagation()
@@ -343,7 +354,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.addCard} 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="propcard" card={card}/>
             <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
@@ -357,7 +370,7 @@
           <Icon type="tool" />
         </Popover>
         {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}>
-          {card.subcards.map((subcard) => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
+          {card.subcards.map((subcard) => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
         </Carousel> : null}
       </div>
     )
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index 0b11823..2da2eaf 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -1282,7 +1282,6 @@
     newcard.execSuccess = 'grid'
     newcard.execError = 'never'
     newcard.popClose = 'never'
-    newcard.errorTime = 10
     newcard.verify = null
     newcard.show = 'icon'
 
diff --git a/src/menu/components/chart/antv-scatter/index.jsx b/src/menu/components/chart/antv-scatter/index.jsx
index 3adb118..b9ae970 100644
--- a/src/menu/components/chart/antv-scatter/index.jsx
+++ b/src/menu/components/chart/antv-scatter/index.jsx
@@ -313,7 +313,6 @@
     newcard.execSuccess = 'grid'
     newcard.execError = 'never'
     newcard.popClose = 'never'
-    newcard.errorTime = 10
     newcard.verify = null
     newcard.show = 'icon'
 
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index 160f512..f7b5e07 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -279,7 +279,6 @@
     newcard.interface = card.setting.interface || ''
     newcard.execSuccess = 'grid'
     newcard.execError = 'never'
-    newcard.errorTime = 10
     newcard.verify = null
     newcard.show = 'button'
     newcard.style = {marginRight: '15px'}
diff --git a/src/tabviews/formtab/actionList/index.jsx b/src/tabviews/formtab/actionList/index.jsx
index 698fcf1..ac97ecd 100644
--- a/src/tabviews/formtab/actionList/index.jsx
+++ b/src/tabviews/formtab/actionList/index.jsx
@@ -305,14 +305,14 @@
       notification.error({
         top: 92,
         message: res.message || res.ErrMesg,
-        duration: btn.errorTime || 10
+        duration: 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
         message: res.message || res.ErrMesg,
-        duration: btn.errorTime || 10
+        duration: 10
       })
     } else if (res.ErrCode === 'NM') {
       message.error(res.message || res.ErrMesg)
diff --git a/src/templates/comtableconfig/source.jsx b/src/templates/comtableconfig/source.jsx
index d5297f9..6743863 100644
--- a/src/templates/comtableconfig/source.jsx
+++ b/src/templates/comtableconfig/source.jsx
@@ -79,7 +79,6 @@
         position: 'toolbar',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'pop',
         icon: 'plus',
         class: 'green',
@@ -93,7 +92,6 @@
         position: 'toolbar',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'pop',
         icon: 'form',
         class: 'purple',
@@ -107,7 +105,6 @@
         position: 'toolbar',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'prompt',
         icon: 'delete',
         class: 'red',
diff --git a/src/templates/formtabconfig/dragelement/index.jsx b/src/templates/formtabconfig/dragelement/index.jsx
index cbd7e79..c75052f 100644
--- a/src/templates/formtabconfig/dragelement/index.jsx
+++ b/src/templates/formtabconfig/dragelement/index.jsx
@@ -131,7 +131,6 @@
         newcard.execSuccess = 'grid'
         newcard.execError = 'never'
         newcard.popClose = 'never'
-        newcard.errorTime = 15
         newcard.verify = null
       }
       
diff --git a/src/templates/formtabconfig/source.jsx b/src/templates/formtabconfig/source.jsx
index 148e0ab..94de283 100644
--- a/src/templates/formtabconfig/source.jsx
+++ b/src/templates/formtabconfig/source.jsx
@@ -73,7 +73,6 @@
         Ot: 'notRequired',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'exec',
         icon: '',
         class: 'border-primary',
@@ -84,7 +83,6 @@
         label: '鍏抽棴',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'exec',
         pageTemplate: '',
         url: '',
diff --git a/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx b/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
index e640a0e..df81400 100644
--- a/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
@@ -110,7 +110,6 @@
       newcard.execSuccess = 'grid'
       newcard.execError = 'never'
       newcard.popClose = 'never'
-      newcard.errorTime = 10
       newcard.verify = null
 
       if (item.subType === 'excelIn') {
diff --git a/src/templates/subtableconfig/source.jsx b/src/templates/subtableconfig/source.jsx
index 4ccd3bf..d8c8aa3 100644
--- a/src/templates/subtableconfig/source.jsx
+++ b/src/templates/subtableconfig/source.jsx
@@ -78,7 +78,6 @@
         position: 'toolbar',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'pop',
         icon: 'plus',
         class: 'green',
@@ -92,7 +91,6 @@
         position: 'grid',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'pop',
         icon: 'form',
         class: 'purple',
@@ -106,7 +104,6 @@
         position: 'toolbar',
         execSuccess: 'grid',
         execError: 'never',
-        errorTime: 15,
         OpenType: 'prompt',
         icon: 'delete',
         class: 'red',
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index f2b9fda..fc9541f 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -214,12 +214,7 @@
   }
 
   delButtons = (items) => {
-    const { copyButtons } = this.state
-
-    this.setState({
-      delButtons: [...this.state.delButtons, ...items],
-      copyButtons: copyButtons.filter(item => !items.includes(item.uuid))
-    })
+    this.setState({ delButtons: [...this.state.delButtons, ...items] })
   }
 
   copyButtons = (items) => {
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index 1ea790f..9317a02 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -402,12 +402,7 @@
   }
 
   delButtons = (items) => {
-    const { copyButtons, delButtons } = this.state
-
-    this.setState({
-      delButtons: [...delButtons, ...items],
-      copyButtons: copyButtons.filter(item => !items.includes(item.uuid))
-    })
+    this.setState({ delButtons: [...this.state.delButtons, ...items] })
   }
 
   copyButtons = (items) => {

--
Gitblit v1.8.0