From 55a1b8402fd258da084df9b8a3935eef8450247c Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期日, 01 八月 2021 18:03:02 +0800
Subject: [PATCH] 2021-08-01

---
 src/menu/components/form/formaction/index.scss             |   16 
 src/pc/modulesource/option.jsx                             |    3 
 src/tabviews/custom/components/form/normal-form/index.scss |    9 
 src/tabviews/zshare/actionList/popupbutton/index.jsx       |    3 
 src/menu/components/form/tab-form/index.scss               |   78 +++
 src/menu/components/form/normal-form/groupform/index.jsx   |   46 ++
 src/mob/modulesource/option.jsx                            |    3 
 src/menu/components/form/normal-form/index.jsx             |   23 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx     |    3 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx    |    3 
 src/menu/components/form/dragtitle/index.jsx               |    4 
 src/menu/components/form/formaction/index.jsx              |   10 
 src/mob/components/formdragelement/index.scss              |    2 
 src/tabviews/zshare/actionList/newpagebutton/index.jsx     |    3 
 src/menu/menushell/card.jsx                                |    5 
 src/tabviews/zshare/actionList/normalbutton/index.jsx      |    3 
 src/views/mobdesign/index.jsx                              |    2 
 src/menu/components/form/tab-form/groupform/index.scss     |   18 
 src/mob/mobshell/card.jsx                                  |    5 
 src/mob/searchconfig/searchdragelement/index.scss          |    2 
 src/tabviews/zshare/actionList/changeuserbutton/index.jsx  |    3 
 src/views/menudesign/index.jsx                             |    2 
 src/menu/modulesource/option.jsx                           |    3 
 src/menu/components/form/formaction/formconfig.jsx         |   28 
 src/tabviews/zshare/actionList/tabbutton/index.jsx         |    3 
 src/menu/components/form/wrapsetting/settingform/index.jsx |   20 
 src/menu/components/share/pastecomponent/index.jsx         |    2 
 src/views/pcdesign/index.jsx                               |    2 
 src/menu/components/form/dragtitle/index.scss              |   50 ++
 src/menu/components/form/tab-form/index.jsx                |  744 +++++++++++++++++++++++++++++++++
 src/pc/menushell/card.jsx                                  |    5 
 src/menu/stylecontroller/styleInput/index.jsx              |    2 
 src/mob/components/tabs/tabcomponents/card.jsx             |    5 
 src/menu/pastecontroller/index.jsx                         |   11 
 src/tabviews/zshare/actionList/printbutton/index.jsx       |    3 
 src/menu/components/group/groupcomponents/card.jsx         |    5 
 src/mob/components/topbar/normal-navbar/index.jsx          |    2 
 src/menu/components/form/tab-form/groupform/index.jsx      |  147 ++++++
 src/menu/components/tabs/tabcomponents/card.jsx            |    5 
 39 files changed, 1,207 insertions(+), 76 deletions(-)

diff --git a/src/menu/components/form/dragtitle/index.jsx b/src/menu/components/form/dragtitle/index.jsx
index 69ce1a4..87c40ac 100644
--- a/src/menu/components/form/dragtitle/index.jsx
+++ b/src/menu/components/form/dragtitle/index.jsx
@@ -4,7 +4,7 @@
 import Card from './card'
 import './index.scss'
 
-const Container = ({list, selectId, handleList, handleGroup, closeGroup, selectGroup}) => {
+const Container = ({list, selectId, tabtype, handleList, handleGroup, closeGroup, selectGroup}) => {
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -44,7 +44,7 @@
   }
 
   return (
-    <div className="normal-form-titles" >
+    <div className={'normal-form-titles ' + (tabtype || '') } >
       {cards.map(card => (
         <Card
           id={card.uuid}
diff --git a/src/menu/components/form/dragtitle/index.scss b/src/menu/components/form/dragtitle/index.scss
index 100acac..f4413f1 100644
--- a/src/menu/components/form/dragtitle/index.scss
+++ b/src/menu/components/form/dragtitle/index.scss
@@ -36,4 +36,54 @@
       background: #1890ff;
     }
   }
+}
+.normal-form-titles.mktab {
+  font-size: 16px;
+  line-height: 36px;
+  min-height: 36px;
+  margin-bottom: 16px;
+  border-bottom: 1px solid #d9d9d9;
+  .form-sort {
+    display: none;
+  }
+  .page-card {
+    margin-bottom: 0px;
+    border-bottom: 2px solid transparent;
+  }
+  .page-card::before {
+    display: none;
+  }
+  .page-card.active {
+    border-bottom-color: #1890ff;
+  }
+}
+.normal-form-titles.mkbtn {
+  font-size: 16px;
+  line-height: 36px;
+  min-height: 36px;
+  margin-bottom: 16px;
+
+  .form-sort {
+    display: none;
+  }
+  .page-card {
+    margin-bottom: 0px;
+    background: #ffffff;
+    color: #1890ff;
+    border: 1px solid #1890ff;
+    border-radius: 0px;
+  }
+  .page-card:first-child {
+    border-radius: 4px 0px 0px 4px;
+  }
+  .page-card:last-child {
+    border-radius: 0px 4px 4px 0px;
+  }
+  .page-card::before {
+    display: none;
+  }
+  .page-card.active {
+    background: #1890ff;
+    color: #ffffff;
+  }
 }
\ No newline at end of file
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index 6eb2048..9b358d1 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -274,19 +274,19 @@
       required: false,
       options: modules
     },
-    {
-      type: 'radio',
-      key: 'enable',
-      label: '鏄惁鏄剧ず',
-      initVal: card.enable || 'true',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏄剧ず'
-      }, {
-        value: 'false',
-        text: '闅愯棌'
-      }]
-    },
+    // {
+    //   type: 'radio',
+    //   key: 'enable',
+    //   label: '鏄惁鏄剧ず',
+    //   initVal: card.enable || 'true',
+    //   required: false,
+    //   options: [{
+    //     value: 'true',
+    //     text: '鏄剧ず'
+    //   }, {
+    //     value: 'false',
+    //     text: '闅愯棌'
+    //   }]
+    // }
   ]
 }
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index 8127e42..a1819fd 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -53,7 +53,7 @@
     const { group } = this.props
 
     let _style = element.style ? fromJS(element.style).toJS() : {}
-    let options = ['font', 'border', 'padding', 'margin', 'backgroundColor']
+    let options = ['font', 'border', 'padding', 'margin', 'backgroundColor', 'width']
 
     this.setState({
       card: element
@@ -195,13 +195,13 @@
 
     return (
       <div className="mk-form-action">
-        {group.sort !== 1 ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+        {group.prevButton && group.prevButton.enable !== 'false' && group.sort !== 1 ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <Icon className="edit" title="缂栬緫" type="edit" onClick={() => this.handleAction(group.prevButton)} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => this.handleStyle(group.prevButton)} type="font-colors" />
           </div>
         } trigger="hover">
-          <Button type="link" className={'prev ' + group.prevButton.enable} style={resetStyle(group.prevButton.style)}>{group.prevButton.label}</Button>
+          <Button type="link" className="prev" style={resetStyle(group.prevButton.style)}>{group.prevButton.label}</Button>
         </Popover> : null}
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
@@ -212,13 +212,13 @@
         } trigger="hover">
           <Button type="link" className="submit mk-primary" onDoubleClick={this.changeMenu} style={resetStyle(group.subButton.style)}>{group.subButton.label}</Button>
         </Popover>
-        {group.sort !== config.subcards.length ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+        {group.nextButton && group.nextButton.enable !== 'false' && group.sort !== config.subcards.length ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <Icon className="edit" title="缂栬緫" type="edit" onClick={() => this.handleAction(group.nextButton)} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => this.handleStyle(group.nextButton)} type="font-colors" />
           </div>
         } trigger="hover">
-          <Button type="link" className={'skip ' + group.nextButton.enable} style={resetStyle(group.nextButton.style)}>{group.nextButton.label}</Button>
+          <Button type="link" className="skip" style={resetStyle(group.nextButton.style)}>{group.nextButton.label}</Button>
         </Popover> : null}
         {/* 缂栬緫鎸夐挳锛氬鍒躲�佺紪杈� */}
         <Modal
diff --git a/src/menu/components/form/formaction/index.scss b/src/menu/components/form/formaction/index.scss
index 1ed5878..88793fc 100644
--- a/src/menu/components/form/formaction/index.scss
+++ b/src/menu/components/form/formaction/index.scss
@@ -4,24 +4,14 @@
   padding-bottom: 10px;
 
   .prev {
-    margin-right: 15px;
-  }
-  .prev.false {
-    span {
-      text-decoration: line-through;
-    }
+    height: auto;
   }
   .submit {
     border: none;
     height: auto;
   }
   .skip {
-    position: absolute;
-    right: 5px;
-  }
-  .skip:not(.true) {
-    span {
-      text-decoration: line-through;
-    }
+    float: right;
+    height: auto;
   }
 }
diff --git a/src/menu/components/form/normal-form/groupform/index.jsx b/src/menu/components/form/normal-form/groupform/index.jsx
index 488cd6c..4f56a21 100644
--- a/src/menu/components/form/normal-form/groupform/index.jsx
+++ b/src/menu/components/form/normal-form/groupform/index.jsx
@@ -144,6 +144,52 @@
               )}
             </Form.Item>
           </Col> : null}
+          <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="绗竴缁勪笉鏄剧ず銆�">
+                <Icon type="question-circle" />
+                涓婁竴姝�
+              </Tooltip>
+            }>
+              {getFieldDecorator('prevEnable', {
+                initialValue: group.prevButton.enable
+              })(
+                <Radio.Group>
+                  <Radio value="true">鏄剧ず</Radio>
+                  <Radio value="false">闅愯棌</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          <Col span={12}>
+            <Form.Item label="鎻愪氦">
+              {getFieldDecorator('subEnable', {
+                initialValue: group.subButton.enable
+              })(
+                <Radio.Group>
+                  <Radio value="true">鏄剧ず</Radio>
+                  <Radio value="false">闅愯棌</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鏈�鍚庝竴缁勪笉鏄剧ず銆�">
+                <Icon type="question-circle" />
+                璺宠繃
+              </Tooltip>
+            }>
+              {getFieldDecorator('nextEnable', {
+                initialValue: group.nextButton.enable
+              })(
+                <Radio.Group>
+                  <Radio value="true">鏄剧ず</Radio>
+                  <Radio value="false">闅愯棌</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
         </Row>
       </Form>
     )
diff --git a/src/menu/components/form/normal-form/index.jsx b/src/menu/components/form/normal-form/index.jsx
index 4835ca7..3ad8ebf 100644
--- a/src/menu/components/form/normal-form/index.jsx
+++ b/src/menu/components/form/normal-form/index.jsx
@@ -79,9 +79,9 @@
           sort: 1,
           style: {},
           fields: [],
-          prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'true'},
-          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}},
-          nextButton: {label: '璺宠繃', type: 'next', enable: 'false'}
+          prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'true', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
+          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+          nextButton: {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
         }]
       }
 
@@ -211,9 +211,9 @@
       sort: card.subcards.length + 1,
       style: {},
       fields: [],
-      prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'true'},
-      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}},
-      nextButton: {label: '璺宠繃', type: 'next', enable: 'false'}
+      prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'true', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
+      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+      nextButton: {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
     }
 
     card.subcards.push(newcard)
@@ -287,10 +287,19 @@
   }
 
   handleGroupSubmit = () => {
-    const { group } = this.state
+    let group = fromJS(this.state.group).toJS()
 
     this.groupRef.handleConfirm().then(res => {
+      group.prevButton.enable = res.prevEnable
+      group.subButton.enable = res.subEnable
+      group.nextButton.enable = res.nextEnable
+
+      delete res.prevEnable
+      delete res.subEnable
+      delete res.nextEnable
+
       group.setting = res
+
       this.setState({groupvisible: false})
       this.updateGroup(group)
     })
diff --git a/src/menu/components/form/tab-form/groupform/index.jsx b/src/menu/components/form/tab-form/groupform/index.jsx
new file mode 100644
index 0000000..2929541
--- /dev/null
+++ b/src/menu/components/form/tab-form/groupform/index.jsx
@@ -0,0 +1,147 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input, Radio, Select } from 'antd'
+import { formRule } from '@/utils/option.js'
+import './index.scss'
+
+class SettingForm extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,     // 瀛楀吀椤�
+    group: PropTypes.object,    // 琛ㄥ崟閰嶇疆淇℃伅
+    inputSubmit: PropTypes.any  // 鍥炶溅鎻愪氦浜嬩欢
+  }
+
+  state = {
+    fields: null,
+    appType: sessionStorage.getItem('appType')
+  }
+
+  UNSAFE_componentWillMount () {
+    const { group } = this.props
+    const { appType } = this.state
+    let fields = []
+
+    if (appType === 'mob') {
+      group.fields.forEach(f => {
+        if (f.field && ['text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
+          fields.push(f)
+        }
+      })
+    } else {
+      group.fields.forEach(f => {
+        if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
+          fields.push(f)
+        }
+      })
+    }
+
+    this.setState({
+      fields: fields
+    })
+  }
+
+  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 { group, dict } = this.props
+    const { getFieldDecorator } = this.props.form
+    const { fields, appType } = this.state
+
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <Form {...formItemLayout} className="ant-advanced-search-form modal-setting-form">
+        <Row gutter={24}>
+          <Col span={12}>
+            <Form.Item label="鏍囬">
+              {getFieldDecorator('title', {
+                initialValue: group.setting.title,
+                rules: [
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
+                  }
+                ]
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+          <Col span={12}>
+            <Form.Item label="鐒︾偣">
+              {getFieldDecorator('focus', {
+                initialValue: group.setting.focus || ''
+              })(
+                <Select
+                  showSearch
+                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                >
+                  <Select.Option value="">
+                    {dict['model.empty']}
+                  </Select.Option>
+                  {fields.map(option =>
+                    <Select.Option id={option.uuid} title={option.label} key={option.uuid} value={option.field}>
+                      {option.label}
+                    </Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+          {appType !== 'mob' ? <Col span={12}>
+            <Form.Item label="琛ㄥ崟鎺掑垪">
+              {getFieldDecorator('align', {
+                initialValue: group.setting.align || 'left_right'
+              })(
+                <Radio.Group>
+                  <Radio value="left_right">宸﹀彸</Radio>
+                  <Radio value="up_down">涓婁笅</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
+          <Col span={12}>
+            <Form.Item label="鎻愪氦">
+              {getFieldDecorator('subEnable', {
+                initialValue: group.subButton.enable
+              })(
+                <Radio.Group>
+                  <Radio value="true">鏄剧ず</Radio>
+                  <Radio value="false">闅愯棌</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/form/tab-form/groupform/index.scss b/src/menu/components/form/tab-form/groupform/index.scss
new file mode 100644
index 0000000..9a74987
--- /dev/null
+++ b/src/menu/components/form/tab-form/groupform/index.scss
@@ -0,0 +1,18 @@
+.ant-advanced-search-form.modal-setting-form {
+  .textarea {
+    .ant-form-item-label {
+      width: 16.3%;
+    }
+    .ant-form-item-control-wrapper {
+      width: 83.33333333%;
+    }
+  }
+  .ant-input-number {
+    width: 100%;
+  }
+  .anticon-question-circle {
+    color: #c49f47;
+    position: relative;
+    left: -3px;
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx
new file mode 100644
index 0000000..bb2b210
--- /dev/null
+++ b/src/menu/components/form/tab-form/index.jsx
@@ -0,0 +1,744 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Icon, Popover, Modal, Button, Switch, notification } from 'antd'
+import moment from 'moment'
+
+import Api from '@/api'
+import asyncComponent from '@/utils/asyncComponent'
+import asyncIconComponent from '@/utils/asyncIconComponent'
+import { getModalForm } from '@/templates/zshare/formconfig'
+import { resetStyle } from '@/utils/utils-custom.js'
+import MKEmitter from '@/utils/events.js'
+import Utils from '@/utils/utils.js'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import './index.scss'
+
+const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
+const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
+const WrapComponent = asyncIconComponent(() => import('@/menu/components/form/wrapsetting'))
+const CardComponent = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
+const MobCardComponent = asyncComponent(() => import('@/mob/components/formdragelement'))
+const FormTitle = asyncComponent(() => import('../dragtitle'))
+const GroupForm = asyncComponent(() => import('./groupform'))
+const FormAction = asyncComponent(() => import('../formaction'))
+const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
+const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
+const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
+const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
+
+const { confirm } = Modal
+
+class PropCardEditComponent extends Component {
+  static propTpyes = {
+    card: PropTypes.object,
+    deletecomponent: PropTypes.func,
+    updateConfig: PropTypes.func,
+  }
+
+  state = {
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    appType: sessionStorage.getItem('appType'),
+    card: null,
+    back: false,
+    group: null,
+    showField: false,
+    visible: false,
+    editform: null,
+    formlist: null,
+    sqlVerifing: false,
+    standardform: null
+  }
+
+  UNSAFE_componentWillMount () {
+    const { card } = this.props
+
+    if (card.isNew) {
+      let _card = {
+        uuid: card.uuid,
+        type: card.type,
+        floor: card.floor,
+        tabId: card.tabId || '',
+        parentId: card.parentId || '',
+        format: 'object',   // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡
+        pageable: false,    // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
+        switchable: false,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
+        dataName: card.dataName || '',
+        width: card.width || 24,
+        name: card.name,
+        subtype: card.subtype,
+        setting: { },
+        wrap: { name: card.name, width: card.width || 24, datatype: 'static', groupLabel: 'show', color: '#1890ff', tabtype: 'mktab' },
+        style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
+        columns: [],
+        scripts: [],
+        subcards: [{
+          uuid: Utils.getuuid(),
+          setting: {title: '绗竴姝�', align: 'left_right'},
+          sort: 1,
+          style: {},
+          fields: [],
+          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+        }]
+      }
+
+      if (card.config) {
+        let config = fromJS(card.config).toJS()
+
+        _card.wrap = config.wrap
+        _card.wrap.name = card.name
+        _card.style = config.style
+
+        _card.subcards = config.subcards.map(scard => {
+          scard.uuid = Utils.getuuid()
+          scard.fields = scard.fields.map(elem => {
+            elem.uuid = Utils.getuuid()
+            return elem
+          })
+          return scard
+        })
+      }
+      this.setState({
+        card: _card,
+        group: _card.subcards[0] || null
+      })
+      this.props.updateConfig(_card)
+    } else {
+      let _card = fromJS(card).toJS()
+      this.setState({
+        card: _card,
+        group: _card.subcards[0] || null
+      })
+    }
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('submitStyle', this.getStyle)
+    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('submitStyle', this.getStyle)
+    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
+  }
+
+  updateComponentStyle = (parentId, keys, style) => {
+    const { card } = this.state
+
+    if (card.uuid !== parentId) return
+
+    let subcards = card.subcards.map(item => {
+      if (keys.includes(item.uuid)) {
+        item.style = {...item.style, ...style}
+      }
+      return item
+    })
+
+    this.setState({card: {...card, subcards: []}}, () => {
+      this.updateComponent({...card, subcards: subcards})
+    })
+  }
+
+  /**
+   * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
+   */
+  updateComponent = (component) => {
+    this.setState({
+      card: component
+    })
+
+    component.width = component.wrap.width
+    component.name = component.wrap.name
+
+    this.props.updateConfig(component)
+  }
+
+  /**
+   * @description 鍗曚釜鍗$墖淇℃伅鏇存柊
+   */
+  updateCard = (cell) => {
+    let card = fromJS(this.state.card).toJS()
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === cell.uuid) return cell
+      return item
+    })
+
+    this.setState({card})
+
+    this.props.updateConfig(card)
+  }
+
+  changeStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style)
+  }
+
+  getStyle = (comIds, style) => {
+    const { card } = this.state
+
+    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
+
+    let _card = {...card, style}
+
+    this.setState({
+      card: _card
+    })
+    
+    this.props.updateConfig(_card)
+  }
+
+  addCard = () => {
+    let card = fromJS(this.state.card).toJS()
+
+    let newcard = {
+      uuid: Utils.getuuid(),
+      setting: { title: `绗�${card.subcards.length + 1}姝, align: 'left_right' },
+      sort: card.subcards.length + 1,
+      style: {},
+      fields: [],
+      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+    }
+
+    card.subcards.push(newcard)
+    
+    this.setState({
+      card,
+      group: newcard,
+      groupvisible: true
+    })
+    this.props.updateConfig(card)
+  }
+
+  changecards = (list) => {
+    let card = fromJS(this.state.card).toJS()
+    card.subcards = list.map((item, index) => {
+      item.sort = index + 1
+      return item
+    })
+
+    this.setState({card})
+    this.props.updateConfig(card)
+  }
+
+  selectGroup = (item) => {
+    this.setState({
+      group: item
+    })
+  }
+
+  changeGroup = (item) => {
+    this.setState({
+      group: item,
+      groupvisible: true
+    })
+  }
+
+  closeGroup = (cell) => {
+    const { group } = this.state
+    let card = fromJS(this.state.card).toJS()
+    const _this = this
+
+    confirm({
+      content: '纭畾鍒犻櫎鍒嗙粍鍚楋紵',
+      onOk() {
+        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
+        let _group = group
+
+        if (group.uuid === cell.uuid) {
+          _group = card.subcards[0] || null
+        }
+
+        _this.setState({card, group: _group})
+        _this.props.updateConfig(card)
+      },
+      onCancel() {}
+    })
+  }
+
+  updateGroup = (group) => {
+    let card = fromJS(this.state.card).toJS()
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === group.uuid) {
+        return group
+      }
+      return item
+    })
+
+    this.setState({card, group})
+    this.props.updateConfig(card)
+  }
+
+  handleGroupSubmit = () => {
+    let group = fromJS(this.state.group).toJS()
+
+    this.groupRef.handleConfirm().then(res => {
+      group.subButton.enable = res.subEnable
+
+      delete res.subEnable
+
+      group.setting = res
+
+      this.setState({groupvisible: false})
+      this.updateGroup(group)
+    })
+  }
+  
+  changecols = (type) => {
+    let card = fromJS(this.state.card).toJS()
+    let config = fromJS(this.state.group).toJS()
+    let _this = this
+
+    config.fields = config.fields.map(item => {
+      item.labelwidth = 33.3
+      item.span = 24
+      if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
+        if (type === 2) {
+          item.labelwidth = 16.3
+        } else if (type === 3) {
+          item.labelwidth = 10.5
+        } else if (type === 4) {
+          item.labelwidth = 8.3
+        }
+      } else if (type === 2) {
+        item.span = 12
+      } else if (type === 3) {
+        item.span = 8
+      } else if (type === 4) {
+        item.span = 6
+      }
+      return item
+    })
+    
+    confirm({
+      content: `纭畾鍒囨崲涓�${type}鍒楀悧锛焋,
+      onOk() {
+        card.subcards = card.subcards.map(item => {
+          if (item.uuid === config.uuid) {
+            return config
+          }
+          return item
+        })
+        _this.setState({group: config, card})
+        _this.props.updateConfig(card)
+      },
+      onCancel() {}
+    })
+  }
+
+  handleList = (list, newcard) => {
+    let group = fromJS(this.state.group).toJS()
+    let card = fromJS(this.state.card).toJS()
+
+    group.fields = list
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === group.uuid) {
+        return group
+      }
+      return item
+    })
+
+    this.setState({card, group}, () => {
+      if (newcard) {
+        this.handleForm(newcard)
+      }
+    })
+    this.props.updateConfig(card)
+  }
+
+  closeForm = (cell) => {
+    let group = fromJS(this.state.group).toJS()
+    let card = fromJS(this.state.card).toJS()
+    let _this = this
+
+    group.fields = group.fields.filter(item => item.uuid !== cell.uuid)
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === group.uuid) {
+        return group
+      }
+      return item
+    })
+
+    confirm({
+      content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
+      onOk() {
+        _this.setState({card, group})
+        _this.props.updateConfig(card)
+      },
+      onCancel() {}
+    })
+  }
+
+  addForm = () => {
+    const { appType } = this.state
+    let group = fromJS(this.state.group).toJS()
+    let lastItem = group.fields[group.fields.length - 1]
+    let span = appType === 'mob' ? 24 : 12
+    if (lastItem && lastItem.span) {
+      span = lastItem.span
+    }
+
+    let newcard = {
+      uuid: Utils.getuuid(),
+      label: '',
+      field: '',
+      initval: '',
+      type: 'text',
+      resourceType: '0',
+      setAll: 'false',
+      span: span,
+      labelwidth: 33.3,
+      options: [],
+      dataSource: '',
+      decimal: 0,
+      orderType: 'asc',
+      readonly: 'false',
+      required: 'true',
+      focus: true
+    }
+
+    group.fields.push(newcard)
+
+    this.setState({group}, () => {
+      this.handleForm(newcard)
+    })
+  }
+
+  editModalCancel = () => {
+    let group = fromJS(this.state.group).toJS()
+    group.fields = group.fields.filter(item => !item.focus)
+
+    this.setState({group, visible: false, editform: null})
+    this.updateGroup(group)
+  }
+
+  /**
+   * @description 琛ㄥ崟缂栬緫
+   */
+  handleForm = (_item) => {
+    const { card, group, appType } = this.state
+    let _form = fromJS(_item).toJS()
+    let _inputfields = []
+    let _tabfields = []
+    let _linkableFields = []
+    let _linksupFields = [{
+      value: '',
+      text: '绌�'
+    }]
+    let standardform = null
+
+    _inputfields = group.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
+    if (appType === 'mob') {
+      _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number'].includes(item.type))
+    } else {
+      _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
+    }
+    _tabfields.unshift({field: '', text: '鍘熻〃鍗�'})
+
+    let uniq = new Map()
+    uniq.set(_form.field, true)
+    let index = null
+    group.fields.forEach((item, i) => {
+      if (_form.uuid === item.uuid) {
+        index = i
+      }
+      
+      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
+      if (item.field && !uniq.has(item.field)) {
+        uniq.set(item.field, true)
+
+        _linkableFields.push({
+          value: item.field,
+          text: item.label + ' (琛ㄥ崟)'
+        })
+        _linksupFields.push({
+          value: item.field,
+          text: item.label
+        })
+      }
+    })
+    if (index !== null) {
+      if (index === 0) {
+        standardform = group.fields[index + 1] || null
+      } else {
+        standardform = group.fields[index - 1] || null
+      }
+    }
+
+    card.columns.forEach(col => {
+      if (col.field && !uniq.has(col.field)) {
+        uniq.set(col.field, true)
+
+        _linkableFields.push({
+          value: col.field,
+          text: col.label + ' (鏄剧ず鍒�)'
+        })
+      }
+    })
+
+    if (_form.linkSubField && _form.linkSubField.length > 0) {
+      let fields = _inputfields.map(item => item.field)
+      _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item))
+    }
+
+    if (appType !== 'mob' && !_form.span && standardform && standardform.span) {
+      _form.span = standardform.span
+      _form.labelwidth = standardform.labelwidth
+    }
+
+    this.setState({
+      standardform,
+      visible: true,
+      editform: _form,
+      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, false)
+    })
+  }
+
+  /**
+   * @description 缂栬緫鍚庢彁浜�
+   * 1銆佽幏鍙栫紪杈戝悗鐨勮〃鍗曚俊鎭�
+   * 2銆佸幓闄ゅ彲鑳藉瓨鍦ㄧ殑绀轰緥琛ㄥ崟
+   * 3銆侀�氳繃loading鍒锋柊
+   */
+  handleSubmit = () => {
+    this.formRef.handleConfirm().then(res => {
+      let _config = fromJS(this.state.group).toJS()
+      let fieldrepet = false // 瀛楁閲嶅
+      let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
+
+      _config.fields = _config.fields.map(item => {
+        if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
+          fieldrepet = true
+        } else if (res.label && item.uuid !== res.uuid && item.label === res.label) {
+          labelrepet = true
+        }
+
+        if (item.uuid === res.uuid) {
+          return res
+        } else {
+          return item
+        }
+      })
+
+      if (fieldrepet) {
+        notification.warning({
+          top: 92,
+          message: '瀛楁宸插瓨鍦紒',
+          duration: 10
+        })
+        return
+      } else if (labelrepet) {
+        notification.warning({
+          top: 92,
+          message: '鍚嶇О宸插瓨鍦紒',
+          duration: 10
+        })
+        return
+      }
+
+      if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+        this.setState({
+          sqlVerifing: true
+        })
+
+        let param = {
+          func: 's_debug_sql',
+          exec_type: 'y',
+          LText: res.dataSource
+        }
+
+        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        
+        param.LText = Utils.formatOptions(param.LText)
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.secretkey = Utils.encrypt('', param.timestamp)
+
+        if (window.GLOB.mainSystemApi && res.database === 'sso') {
+          param.rduri = window.GLOB.mainSystemApi
+        }
+        
+        Api.getLocalConfig(param).then(result => {
+          if (result.status) {
+            this.setState({
+              sqlVerifing: false,
+              editform: null,
+              visible: false
+            })
+            this.updateGroup(_config)
+          } else {
+            this.setState({sqlVerifing: false})
+            
+            Modal.error({
+              title: result.message
+            })
+          }
+        })
+      } else {
+        this.setState({
+          editform: null,
+          visible: false
+        })
+        this.updateGroup(_config)
+      }
+    })
+  }
+
+  pasteForm = (res) => {
+    let _config = fromJS(this.state.group).toJS()
+    let fieldrepet = false // 瀛楁閲嶅
+    let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
+
+    _config.fields.forEach(item => {
+      if (res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
+        fieldrepet = true
+      } else if (res.label && item.label === res.label) {
+        labelrepet = true
+      }
+    })
+
+    if (fieldrepet) {
+      notification.warning({
+        top: 92,
+        message: '瀛楁宸插瓨鍦紒',
+        duration: 10
+      })
+      return
+    } else if (labelrepet) {
+      notification.warning({
+        top: 92,
+        message: '鍚嶇О宸插瓨鍦紒',
+        duration: 10
+      })
+      return
+    }
+    _config.fields.push(res)
+
+    this.updateGroup(_config)
+
+    this.handleForm(res)
+
+    notification.success({
+      top: 92,
+      message: '绮樿创鎴愬姛锛�',
+      duration: 2
+    })
+  }
+
+  clickComponent = (e) => {
+    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
+      e.stopPropagation()
+      MKEmitter.emit('clickComponent', this.state.card)
+    }
+  }
+
+  render() {
+    const { card, dict, group, appType } = this.state
+
+    return (
+      <div className="menu-normal-form-edit-box" style={resetStyle(card.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">
+            <Icon className="plus" title="娣诲姞鍒嗙粍" onClick={this.addCard} type="plus" />
+            <WrapComponent config={card} updateConfig={this.updateComponent} />
+            <CopyComponent type="propcard" card={card}/>
+            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
+            <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
+            <UserComponent config={card}/>
+            <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
+            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
+            {card.wrap.datatype === 'static' ? <Icon style={{color: '#eeeeee', cursor: 'not-allowed'}} type="setting"/> : null}
+          </div>
+        } trigger="hover">
+          <Icon type="tool" />
+        </Popover>
+        <FormTitle
+          list={card.subcards}
+          tabtype={card.wrap.tabtype || ''}
+          selectId={group ? group.uuid : ''}
+          handleList={this.changecards}
+          handleGroup={this.changeGroup}
+          closeGroup={this.closeGroup}
+          selectGroup={this.selectGroup}
+        />
+        {group ? <div className="form-area">
+          <Icon className="plus" title="娣诲姞琛ㄥ崟" onClick={this.addForm} type="plus" />
+          <FieldsComponent config={group} type="form" updatefield={this.updateGroup} />
+          <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
+          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1鍒�</Button> : null}
+          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2鍒�</Button> : null}
+          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3鍒�</Button> : null}
+          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4鍒�</Button> : null}
+          <div style={{clear: 'both'}}></div>
+          {appType !== 'mob' ? <CardComponent
+            list={group.fields}
+            setting={group.setting}
+            showField={this.state.showField}
+            placeholder={dict['header.form.modal.placeholder']}
+            handleList={this.handleList}
+            handleForm={this.handleForm}
+            closeForm={this.closeForm}
+          /> : <MobCardComponent
+            list={group.fields}
+            setting={group.setting}
+            showField={this.state.showField}
+            handleList={this.handleList}
+            handleForm={this.handleForm}
+            closeForm={this.closeForm}
+          />}
+          <FormAction config={card} group={group} updateconfig={this.updateGroup}/>
+        </div> : null}
+        <Modal
+          title="鍒嗙粍缂栬緫"
+          visible={this.state.groupvisible}
+          width={850}
+          maskClosable={false}
+          onCancel={() => this.setState({groupvisible: false})}
+          onOk={this.handleGroupSubmit}
+          destroyOnClose
+        >
+          <GroupForm
+            dict={dict}
+            group={group}
+            inputSubmit={this.handleGroupSubmit}
+            wrappedComponentRef={(inst) => this.groupRef = inst}
+          />
+        </Modal>
+        <Modal
+          title={this.state.dict['model.edit']}
+          visible={this.state.visible}
+          width={850}
+          onCancel={this.editModalCancel}
+          onOk={this.handleSubmit}
+          confirmLoading={this.state.sqlVerifing}
+          destroyOnClose
+        >
+          <ModalForm
+            dict={this.state.dict}
+            card={this.state.editform}
+            formlist={this.state.formlist}
+            inputSubmit={this.handleSubmit}
+            standardform={this.state.standardform}
+            wrappedComponentRef={(inst) => this.formRef = inst}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+export default PropCardEditComponent
\ No newline at end of file
diff --git a/src/menu/components/form/tab-form/index.scss b/src/menu/components/form/tab-form/index.scss
new file mode 100644
index 0000000..0fb6111
--- /dev/null
+++ b/src/menu/components/form/tab-form/index.scss
@@ -0,0 +1,78 @@
+.menu-normal-form-edit-box {
+  position: relative;
+  box-sizing: border-box;
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  min-height: 30px;
+  
+  .card-control {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    .anticon-tool {
+      right: auto;
+      left: 1px;
+      padding: 1px;
+    }
+  }
+  .anticon-tool {
+    position: absolute;
+    z-index: 2;
+    font-size: 16px;
+    right: 1px;
+    top: 1px;
+    cursor: pointer;
+    padding: 5px;
+    background: rgba(255, 255, 255, 0.55);
+  }
+
+  .page-card {
+    position: relative;
+    background: #ffffff;
+    border-radius: 2px;
+    margin-bottom: 15px;
+  }
+  .form-area {
+    position: relative;
+    >.plus {
+      color: #26C281;
+      cursor: pointer;
+      padding: 4px 10px;
+    }
+    >button {
+      float: right;
+      margin-right: 10px;
+    }
+    >.mk-cols-change {
+      height: 24px;
+      padding: 0 10px;
+    }
+    >.quickly-add {
+      display: inline-block;
+      margin-left: 10px;
+      button {
+        color: #1890ff;
+        background: transparent;
+        border: none;
+        box-shadow: none;
+        padding: 0;
+        height: 24px;
+      }
+    }
+    .modal-fields-row {
+      padding-top: 10px;
+      padding-bottom: 30px;
+    }
+  }
+}
+.menu-normal-form-edit-box::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+.menu-normal-form-edit-box:hover {
+  z-index: 1;
+  box-shadow: 0px 0px 4px #1890ff;
+}
diff --git a/src/menu/components/form/wrapsetting/settingform/index.jsx b/src/menu/components/form/wrapsetting/settingform/index.jsx
index ea4257c..83e7804 100644
--- a/src/menu/components/form/wrapsetting/settingform/index.jsx
+++ b/src/menu/components/form/wrapsetting/settingform/index.jsx
@@ -128,7 +128,7 @@
                 )}
               </Form.Item>
             </Col>
-            <Col span={12}>
+            {config.subtype !== 'tabform' ? <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="琛ㄥ崟鍔犺浇鏃剁殑鐘舵�侊紝褰撳瓧娈靛�间笌琛ㄥ崟缁勭殑鐘舵�佸�间竴鑷存椂锛屽惎鐢ㄥ搴旂殑琛ㄥ崟缁勩��">
                   <Icon type="question-circle" />
@@ -146,7 +146,7 @@
                   </Select>
                 )}
               </Form.Item>
-            </Col>
+            </Col> : null}
             <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="鍔犺浇鏃舵槸鍚︽樉绀哄垎缁勫悕绉般��">
@@ -164,7 +164,19 @@
                 )}
               </Form.Item>
             </Col>
-            <Col span={12}>
+            {config.subtype === 'tabform' ? <Col span={12}>
+              <Form.Item label="鍒嗙粍椋庢牸">
+                {getFieldDecorator('tabtype', {
+                  initialValue: wrap.tabtype || 'mktab'
+                })(
+                  <Radio.Group>
+                    <Radio value="mktab">tab椤�</Radio>
+                    <Radio value="mkbtn">鎸夐挳缁�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            {config.subtype !== 'tabform' ? <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="瀹屾垚鍚庣殑棰滆壊">
                   <Icon type="question-circle" />
@@ -177,7 +189,7 @@
                   <ColorSketch />
                 )}
               </Form.Item>
-            </Col>
+            </Col> : null}
             <Col span={12}>
               <Form.Item label="榛戝悕鍗�">
                 {getFieldDecorator('blacklist', {
diff --git a/src/menu/components/group/groupcomponents/card.jsx b/src/menu/components/group/groupcomponents/card.jsx
index ec99ddf..0e01f26 100644
--- a/src/menu/components/group/groupcomponents/card.jsx
+++ b/src/menu/components/group/groupcomponents/card.jsx
@@ -14,6 +14,7 @@
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const AntvScatter = asyncComponent(() => import('@/menu/components/chart/antv-scatter'))
 const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const AntvDashboard = asyncComponent(() => import('@/menu/components/chart/antv-dashboard'))
 const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card'))
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
@@ -63,8 +64,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'form') {
+    } else if (card.type === 'form' && card.subtype === 'stepform') {
       return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'tabform') {
+      return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'card' && card.subtype === 'datacard') {
       return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
     } else if (card.type === 'card' && card.subtype === 'propcard') {
diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx
index 553d24d..e367d11 100644
--- a/src/menu/components/share/pastecomponent/index.jsx
+++ b/src/menu/components/share/pastecomponent/index.jsx
@@ -148,7 +148,7 @@
         MKEmitter.emit('copyButtons', copyBtns)
       }
 
-      if (config.type === 'form' && config.subtype === 'stepform') {
+      if (config.type === 'form') {
         this.props.updateConfig(res)
         this.setState({visible: false})
         return
diff --git a/src/menu/components/tabs/tabcomponents/card.jsx b/src/menu/components/tabs/tabcomponents/card.jsx
index 32d1080..017966a 100644
--- a/src/menu/components/tabs/tabcomponents/card.jsx
+++ b/src/menu/components/tabs/tabcomponents/card.jsx
@@ -17,6 +17,7 @@
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
 const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
@@ -68,8 +69,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'form') {
+    } else if (card.type === 'form' && card.subtype === 'stepform') {
       return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'tabform') {
+      return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
       return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard} />)
     } else if (card.type === 'card' && card.subtype === 'datacard') {
diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx
index b12b583..327482c 100644
--- a/src/menu/menushell/card.jsx
+++ b/src/menu/menushell/card.jsx
@@ -19,6 +19,7 @@
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
@@ -69,8 +70,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'form') {
+    } else if (card.type === 'form' && card.subtype === 'stepform') {
       return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'tabform') {
+      return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
       return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'card' && card.subtype === 'datacard') {
diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx
index e9e1833..fe6dd69 100644
--- a/src/menu/modulesource/option.jsx
+++ b/src/menu/modulesource/option.jsx
@@ -30,7 +30,8 @@
   { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 },
   { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 },
   { type: 'menu', url: card2, component: 'balcony', subtype: 'balcony', title: '鍙诞鍔ㄥ崱', width: 24 },
-  { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟锛堝垎姝ワ級', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'tabform', title: '琛ㄥ崟锛坱ab椤碉級', width: 24 },
   { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '杞挱-闈欐�佹暟鎹�', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 },
diff --git a/src/menu/pastecontroller/index.jsx b/src/menu/pastecontroller/index.jsx
index 796dc1c..d97527d 100644
--- a/src/menu/pastecontroller/index.jsx
+++ b/src/menu/pastecontroller/index.jsx
@@ -153,6 +153,17 @@
         }
         return col
       })
+    } else if (item.type === 'form') {
+      item.subcards = item.subcards.map(cell => {
+        cell.uuid = Utils.getuuid()
+
+        cell.fields = cell.fields.map(m => {
+          m.uuid = Utils.getuuid()
+  
+          return m
+        })
+        return cell
+      })
     }
 
     if (item.btnlog) {
diff --git a/src/menu/stylecontroller/styleInput/index.jsx b/src/menu/stylecontroller/styleInput/index.jsx
index eadf6ef..6d9dee9 100644
--- a/src/menu/stylecontroller/styleInput/index.jsx
+++ b/src/menu/stylecontroller/styleInput/index.jsx
@@ -106,7 +106,7 @@
     const { unit } = this.state
     let val = e.target.value
 
-    if (/\d+\.$/.test(val)) {
+    if (/\d+\.$|^-$/.test(val)) {
       this.setState({
         value: val
       })
diff --git a/src/mob/components/formdragelement/index.scss b/src/mob/components/formdragelement/index.scss
index 28a32dc..aa3c250 100644
--- a/src/mob/components/formdragelement/index.scss
+++ b/src/mob/components/formdragelement/index.scss
@@ -10,7 +10,7 @@
   }
   .am-list-item {
     font-size: 16px;
-    padding-left: 10px;
+    // padding-left: 10px;
     position: relative;
     display: flex;
     height: 44px;
diff --git a/src/mob/components/tabs/tabcomponents/card.jsx b/src/mob/components/tabs/tabcomponents/card.jsx
index 24acf4d..6e8be3e 100644
--- a/src/mob/components/tabs/tabcomponents/card.jsx
+++ b/src/mob/components/tabs/tabcomponents/card.jsx
@@ -17,6 +17,7 @@
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
 const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
@@ -69,8 +70,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'form') {
+    } else if (card.type === 'form' && card.subtype === 'stepform') {
       return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'tabform') {
+      return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
       return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard} />)
     } else if (card.type === 'card' && card.subtype === 'datacard') {
diff --git a/src/mob/components/topbar/normal-navbar/index.jsx b/src/mob/components/topbar/normal-navbar/index.jsx
index 59a358e..74b39ac 100644
--- a/src/mob/components/topbar/normal-navbar/index.jsx
+++ b/src/mob/components/topbar/normal-navbar/index.jsx
@@ -36,7 +36,7 @@
         width: 24,
         subtype: card.subtype,
         wrap: { type: 'navbar', height: 50, title: 'NavBar', back: 'true', search: 'false', logout: 'false' },
-        style: {borderBottomColor: '#bcbcbc', borderBottomWidth: '1px', paddingLeft: '10px', paddingRight: '10px', lineHeight: '2.8', fontSize: '18px' },
+        style: {boxShadow: '0 0 3px #D9D9D9', shadowColor: '#D9D9D9', shadowBlur: '3px', paddingLeft: '10px', paddingRight: '10px', lineHeight: '2.8', fontSize: '18px' },
       }
 
       if (card.config) {
diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx
index 797d51a..4e8c4e1 100644
--- a/src/mob/mobshell/card.jsx
+++ b/src/mob/mobshell/card.jsx
@@ -17,6 +17,7 @@
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
@@ -87,8 +88,10 @@
       return (<AntvDashboard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'form') {
+    } else if (card.type === 'form' && card.subtype === 'stepform') {
       return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'tabform') {
+      return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
       return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'card' && card.subtype === 'datacard') {
diff --git a/src/mob/modulesource/option.jsx b/src/mob/modulesource/option.jsx
index 417a095..dfc9675 100644
--- a/src/mob/modulesource/option.jsx
+++ b/src/mob/modulesource/option.jsx
@@ -34,7 +34,8 @@
   { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 },
   { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 },
   { type: 'menu', url: card2, component: 'balcony', subtype: 'balcony', title: '鍙诞鍔ㄥ崱', width: 24 },
-  { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟锛堝垎姝ワ級', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'tabform', title: '琛ㄥ崟锛坱ab椤碉級', width: 24 },
   { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24 },
   { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '杞挱-闈欐�佹暟鎹�', width: 24 },
   { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 },
diff --git a/src/mob/searchconfig/searchdragelement/index.scss b/src/mob/searchconfig/searchdragelement/index.scss
index 357ef51..0a803c7 100644
--- a/src/mob/searchconfig/searchdragelement/index.scss
+++ b/src/mob/searchconfig/searchdragelement/index.scss
@@ -10,7 +10,7 @@
   }
   .am-list-item {
     font-size: 16px;
-    padding-left: 10px;
+    // padding-left: 10px;
     position: relative;
     display: flex;
     height: 44px;
diff --git a/src/pc/menushell/card.jsx b/src/pc/menushell/card.jsx
index c3311f6..6e114c7 100644
--- a/src/pc/menushell/card.jsx
+++ b/src/pc/menushell/card.jsx
@@ -17,6 +17,7 @@
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
 const NormalNavbar = asyncComponent(() => import('@/pc/components/navbar/normal-navbar'))
@@ -79,8 +80,10 @@
       return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'navbar') {
       return (<NormalNavbar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'form') {
+    } else if (card.type === 'form' && card.subtype === 'stepform') {
       return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'tabform') {
+      return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'search') {
       return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'pie') {
diff --git a/src/pc/modulesource/option.jsx b/src/pc/modulesource/option.jsx
index b7e6090..59832b5 100644
--- a/src/pc/modulesource/option.jsx
+++ b/src/pc/modulesource/option.jsx
@@ -33,7 +33,8 @@
   { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 },
   { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 },
   { type: 'menu', url: card2, component: 'balcony', subtype: 'balcony', title: '鍙诞鍔ㄥ崱', width: 24 },
-  { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟锛堝垎姝ワ級', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'tabform', title: '琛ㄥ崟锛坱ab椤碉級', width: 24 },
   { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24 },
   { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '杞挱-闈欐�佹暟鎹�', width: 24 },
   { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 },
diff --git a/src/tabviews/custom/components/form/normal-form/index.scss b/src/tabviews/custom/components/form/normal-form/index.scss
index 7547391..a3fbda6 100644
--- a/src/tabviews/custom/components/form/normal-form/index.scss
+++ b/src/tabviews/custom/components/form/normal-form/index.scss
@@ -65,17 +65,14 @@
     position: relative;
     text-align: center;
     padding-bottom: 10px;
-  
-    .prev {
-      margin-right: 15px;
-    }
+
     .submit {
       min-width: 70px;
       border: none;
     }
     .skip {
-      position: absolute;
-      right: 5px;
+      float: right;
+      height: auto;
     }
   }
   .mk-form-action.no-button {
diff --git a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
index 27ccfca..bbee103 100644
--- a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -207,7 +207,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || ''
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index 56bbb05..55277b0 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -467,7 +467,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || 'upload'
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 127a679..7af9862 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -881,7 +881,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || 'download'
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/tabviews/zshare/actionList/newpagebutton/index.jsx b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
index d385c04..bde0cee 100644
--- a/src/tabviews/zshare/actionList/newpagebutton/index.jsx
+++ b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -213,7 +213,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || ''
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 7d03c60..5368ef5 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -1815,7 +1815,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || ''
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/tabviews/zshare/actionList/popupbutton/index.jsx b/src/tabviews/zshare/actionList/popupbutton/index.jsx
index 8b5b86b..a797d90 100644
--- a/src/tabviews/zshare/actionList/popupbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/popupbutton/index.jsx
@@ -207,7 +207,8 @@
       icon = ''
     } else if (show === 'icon') {
       icon = btn.icon || ''
-    } else if (show === 'text') {
+    // } else if (show === 'text') {
+    } else {
       label = btn.label
     }
 
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index 205ef81..d22fe81 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1349,7 +1349,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || ''
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/tabviews/zshare/actionList/tabbutton/index.jsx b/src/tabviews/zshare/actionList/tabbutton/index.jsx
index dd4b82c..f7f654e 100644
--- a/src/tabviews/zshare/actionList/tabbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -205,7 +205,8 @@
         icon = ''
       } else if (show === 'icon') {
         icon = btn.icon || ''
-      } else if (show === 'text') {
+      // } else if (show === 'text') {
+      } else {
         label = btn.label
       }
 
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 85e7fe4..f2b9fda 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -856,7 +856,7 @@
           check(item.components)
           return
         }
-        if (['propcard', 'brafteditor', 'sandbox', 'stepform'].includes(item.subtype) && item.wrap.datatype === 'static') return
+        if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
         if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
   
         if (item.setting) {
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index e983907..45210ac 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -1122,7 +1122,7 @@
           error = `瀵艰埅鏍忋��${item.name}銆嬫湭璁剧疆鑿滃崟鍙傛暟锛乣
         }
 
-        if (['propcard', 'brafteditor', 'sandbox', 'tabbar', 'stepform'].includes(item.subtype) && item.wrap.datatype === 'static') return
+        if (['propcard', 'brafteditor', 'sandbox', 'tabbar', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
         if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
 
         if (item.setting) {
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index bde0d56..080744b 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -1375,7 +1375,7 @@
           check(item.components)
           return
         }
-        if (['propcard', 'brafteditor', 'sandbox', 'stepform'].includes(item.subtype) && item.wrap.datatype === 'static') return
+        if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
         if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
         
         if (item.setting) {

--
Gitblit v1.8.0