From 71d4765ba3cdc4a004687cd37a529b565e9ea9fd Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 06 七月 2021 16:26:29 +0800
Subject: [PATCH] 2021-07-06

---
 src/mob/searchconfig/searchdragelement/index.jsx                          |  123 ++++
 src/templates/zshare/modalform/index.jsx                                  |    4 
 src/mob/searchconfig/groupdragelement/card.jsx                            |   61 ++
 src/mob/searchconfig/groupform/index.scss                                 |   18 
 src/mob/components/topbar/normal-navbar/index.scss                        |   15 
 src/mob/searchconfig/index.jsx                                            |  355 ++++++-----
 src/templates/formtabconfig/index.jsx                                     |    8 
 src/menu/components/form/normal-form/index.jsx                            |    2 
 src/mob/searchconfig/index.scss                                           |   66 +
 src/mob/searchconfig/pastecomponent/index.jsx                             |   23 
 src/templates/zshare/editcomponent/index.jsx                              |   30 
 src/templates/modalconfig/index.jsx                                       |    2 
 src/mob/components/formdragelement/index.scss                             |   24 
 src/mob/searchconfig/settingform/index.scss                               |   18 
 src/mob/modalconfig/index.jsx                                             |   12 
 src/mob/searchconfig/groupform/index.jsx                                  |   90 +++
 src/mob/modalconfig/pastecomponent/index.jsx                              |    4 
 src/mob/searchconfig/groupdragelement/index.jsx                           |   64 ++
 src/mob/searchconfig/searchdragelement/index.scss                         |  148 +++++
 src/mob/searchconfig/groupdragelement/index.scss                          |   27 
 src/templates/zshare/formconfig.jsx                                       |   77 ++
 src/mob/components/topbar/normal-navbar/wrapsetting/settingform/index.jsx |    6 
 src/mob/searchconfig/searchdragelement/card.jsx                           |  132 ++++
 src/menu/components/card/data-card/index.jsx                              |    2 
 src/menu/components/search/main-search/index.jsx                          |    2 
 src/mob/components/formdragelement/card.jsx                               |   10 
 src/mob/searchconfig/settingform/index.jsx                                |  192 ++++++
 src/menu/components/share/actioncomponent/actionform/index.jsx            |    2 
 src/mob/searchconfig/source.jsx                                           |   93 --
 src/mob/components/topbar/normal-navbar/index.jsx                         |   28 
 src/menu/modalconfig/index.jsx                                            |    2 
 src/mob/searchconfig/controller.jsx                                       |   20 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx         |   55 +
 33 files changed, 1,358 insertions(+), 357 deletions(-)

diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 38f568e..4b42656 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -307,7 +307,7 @@
         }
       }
       MKEmitter.emit('changeModal', card, btn)
-    } else if (btn.OpenType === 'popview') {
+    } else if (btn.OpenType === 'popview' && appType !== 'mob') {
       MKEmitter.emit('changePopview', card, btn)
     }
   }
diff --git a/src/menu/components/form/normal-form/index.jsx b/src/menu/components/form/normal-form/index.jsx
index 7b5a75b..f529207 100644
--- a/src/menu/components/form/normal-form/index.jsx
+++ b/src/menu/components/form/normal-form/index.jsx
@@ -9,13 +9,13 @@
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { getModalForm } from '@/templates/zshare/formconfig'
 import { resetStyle } from '@/utils/utils-custom.js'
-import ModalForm from '@/templates/zshare/modalform'
 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'))
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 2bff7e3..2de3892 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -11,7 +11,6 @@
 import { getSearchForm } from '@/templates/zshare/formconfig'
 import { resetStyle } from '@/utils/utils-custom.js'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import SearchForm from '@/templates/sharecomponent/searchcomponent/searchform'
 import DragElement from './dragsearch'
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
@@ -19,6 +18,7 @@
 const { confirm } = Modal
 
 const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
+const SearchForm = asyncIconComponent(() => import('@/templates/sharecomponent/searchcomponent/searchform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index 55483c8..26122e5 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -629,7 +629,7 @@
             </Form.Item>
           </Col>
         )
-      } else if (item.type === 'icon') { // 澶氶��
+      } else if (item.type === 'icon') {
         fields.push(
           <Col span={12} key={index}>
             <Form.Item label={item.label}>
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
index f31feac..cf6bab2 100644
--- a/src/menu/modalconfig/index.jsx
+++ b/src/menu/modalconfig/index.jsx
@@ -12,7 +12,6 @@
 import enUS from '@/locales/en-US/model.js'
 import { getModalForm } from '@/templates/zshare/formconfig'
 
-import ModalForm from '@/templates/zshare/modalform'
 import SourceElement from '@/templates/modalconfig/dragelement/source'
 import SettingForm from '@/templates/modalconfig/settingform'
 import asyncComponent from '@/utils/asyncComponent'
@@ -22,6 +21,7 @@
 const { Panel } = Collapse
 const { confirm } = Modal
 const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
 const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
 const DragElement = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
 const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
diff --git a/src/mob/components/formdragelement/card.jsx b/src/mob/components/formdragelement/card.jsx
index 140de71..7447e32 100644
--- a/src/mob/components/formdragelement/card.jsx
+++ b/src/mob/components/formdragelement/card.jsx
@@ -113,16 +113,18 @@
     }
 
     formItem = (
-    <div className="am-list-item checkbox">
+    <div className={'am-list-item checkbox mk-radio ' + (card.arrange || '')}>
       <div className="am-list-line">
         <div className="am-input-label">{card.label}</div>
         <div className="am-input-control">
-          <div className="mk-radio-group">
+          {card.arrange !== 'line' ? <Checkbox.Group value={[card.initval]}>
+            {options.map(cell => <Checkbox key={cell.key} value={cell.Value}>{cell.Text}</Checkbox>)}
+          </Checkbox.Group> : <div className="mk-radio-group">
             {options.map(cell => (<div key={cell.key} className="mk-radio-wrapper">
               <span className="radio-value">{cell.Text}</span>
               <span className={'radio-check ' + (card.initval === cell.Value ? 'checked' : '')}></span>
             </div>))}
-          </div>
+          </div>}
         </div>
       </div>
     </div>)
@@ -140,7 +142,7 @@
     }
 
     formItem = (
-      <div className="am-list-item checkbox">
+      <div className={'am-list-item checkbox ' + (card.arrange || '')}>
         <div className="am-list-line">
           <div className="am-input-label">{card.label}</div>
           <div className="am-input-control">
diff --git a/src/mob/components/formdragelement/index.scss b/src/mob/components/formdragelement/index.scss
index 2695bc5..28a32dc 100644
--- a/src/mob/components/formdragelement/index.scss
+++ b/src/mob/components/formdragelement/index.scss
@@ -22,7 +22,7 @@
     align-items: center;
 
     .am-list-line {
-      border-bottom: 1PX solid #ddd;
+      border-bottom: 1px solid #ddd;
       align-items: center;
       position: relative;
       display: flex;
@@ -168,6 +168,28 @@
       }
     }
   }
+  .am-list-item.checkbox.mk-radio {
+    .ant-checkbox-inner {
+      border-radius: 50%;
+    }
+  }
+  .am-list-item.checkbox:not(.line) {
+    .ant-checkbox-group {
+      .ant-checkbox-wrapper {
+        float: left;
+        margin-right: 15px;
+        .ant-checkbox + span {
+          border-bottom: none;
+        }
+      }
+    }
+    .mk-radio-group {
+      .mk-radio-wrapper {
+        float: left;
+        margin-right: 15px;
+      }
+    }
+  }
   .split-line {
     color: #1890ff;
     font-size: 16px;
diff --git a/src/mob/components/topbar/normal-navbar/index.jsx b/src/mob/components/topbar/normal-navbar/index.jsx
index 6f0a585..ca764ec 100644
--- a/src/mob/components/topbar/normal-navbar/index.jsx
+++ b/src/mob/components/topbar/normal-navbar/index.jsx
@@ -59,6 +59,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
+    MKEmitter.addListener('submitSearch', this.getSearch)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -73,6 +74,7 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
+    MKEmitter.removeListener('submitSearch', this.getSearch)
   }
   
   /**
@@ -130,8 +132,31 @@
     }
   }
 
-  setSearch = () => {
+  getSearch = (config) => {
+    const { card } = this.state
 
+    if (card.uuid !== config.uuid) return
+
+    this.setState({
+      card: config
+    })
+    
+    this.props.updateConfig(config)
+  }
+
+  setSearch = () => {
+    let card = fromJS(this.state.card).toJS()
+
+    if (!card.search) {
+      card.search = {
+        floor: 1,
+        setting: { type: 'title', field: '', title: '', focus: 'true', btn: 'hidden' },
+        groups: [],
+        fields: []
+      }
+    }
+    this.props.updateConfig(card)
+    MKEmitter.emit('changeSearch', card)
   }
 
   render() {
@@ -141,7 +166,6 @@
     if (_style.shadow) {
       _style.boxShadow = '0 0 4px ' + _style.shadow
     }
-    _style.height = card.wrap.height
 
     return (
       <div className="normal-topbar-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
diff --git a/src/mob/components/topbar/normal-navbar/index.scss b/src/mob/components/topbar/normal-navbar/index.scss
index db9ed7f..c7cd342 100644
--- a/src/mob/components/topbar/normal-navbar/index.scss
+++ b/src/mob/components/topbar/normal-navbar/index.scss
@@ -8,7 +8,7 @@
   background-position: center center;
   background-repeat: no-repeat;
   background-size: cover;
-  min-height: 30px;
+  height: 50px;
   z-index: 3;
   
   .anticon-tool {
@@ -31,6 +31,8 @@
       width: 30px;
       text-align: left;
       color: #1890ff;
+      font-size: 20px;
+      line-height: 50px;
     }
     .am-navbar-title {
       text-align: center;
@@ -42,23 +44,26 @@
       flex: 1;
       padding: 0 5px;
       .search-bar {
-        height: 35px;
-        line-height: 35px;
+        height: 30px;
+        line-height: 30px;
         padding: 0 10px;
         color:rgba(0, 0, 0, 0.65);
-        border: 1px solid #e8e8e8;
-        background: #efefef;
+        border: 1px solid #E9EDF0;
+        background: #E9EDF0;
         border-radius: 4px;
         position: relative;
         top: 50%;
         transform: translateY(-50%);
         cursor: pointer;
+        font-size: 18px;
       }
     }
     .am-navbar-right {
       text-align: right;
       color: #1890ff;
       min-width: 30px;
+      font-size: 20px;
+      line-height: 50px;
       .anticon-search {
         margin-right: 5px;
         padding: 5px;
diff --git a/src/mob/components/topbar/normal-navbar/wrapsetting/settingform/index.jsx b/src/mob/components/topbar/normal-navbar/wrapsetting/settingform/index.jsx
index f1bfc8d..a933aa7 100644
--- a/src/mob/components/topbar/normal-navbar/wrapsetting/settingform/index.jsx
+++ b/src/mob/components/topbar/normal-navbar/wrapsetting/settingform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, InputNumber, Radio, Tooltip, Icon } from 'antd'
+import { Form, Row, Col, Input, Radio, Tooltip, Icon } from 'antd'
 
 import './index.scss'
 
@@ -74,7 +74,7 @@
                 })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
               </Form.Item>
             </Col> : null}
-            <Col span={12}>
+            {/* <Col span={12}>
               <Form.Item label="楂樺害">
                 {getFieldDecorator('height', {
                   initialValue: wrap.height || 50,
@@ -86,7 +86,7 @@
                   ]
                 })(<InputNumber min={30} max={200} precision={0} onPressEnter={this.handleSubmit} />)}
               </Form.Item>
-            </Col>
+            </Col> */}
             <Col span={12}>
               <Form.Item label="杩斿洖">
                 {getFieldDecorator('back', {
diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx
index a91737d..fc634fd 100644
--- a/src/mob/modalconfig/index.jsx
+++ b/src/mob/modalconfig/index.jsx
@@ -12,7 +12,6 @@
 import enUS from '@/locales/en-US/model.js'
 import { getModalForm } from '@/templates/zshare/formconfig'
 
-import ModalForm from '@/templates/zshare/modalform'
 import SourceElement from '@/templates/modalconfig/dragelement/source'
 import SettingForm from '@/templates/modalconfig/settingform'
 import asyncComponent from '@/utils/asyncComponent'
@@ -23,6 +22,7 @@
 const { confirm } = Modal
 const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 const PasteComponent = asyncComponent(() => import('./pastecomponent'))
+const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
 const DragElement = asyncComponent(() => import('@/mob/components/formdragelement'))
 const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
 
@@ -365,6 +365,14 @@
     })
   }
 
+  insert = (config) => {
+    this.setState({
+      config
+    }, () => {
+      this.handleForm(config.fields[config.fields.length - 1])
+    })
+  }
+
   render () {
     const { config, dict } = this.state
 
@@ -391,7 +399,7 @@
             <Button icon="setting" onClick={this.changeSetting}>璁剧疆</Button>
             <Button type="primary" onClick={this.submitConfig}>淇濆瓨</Button>
             <Button onClick={this.cancelConfig}>杩斿洖</Button>
-            <PasteComponent type="menu" Tab={null} insert={this.insert} />
+            <PasteComponent config={config} updateConfig={this.insert} />
             <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
           </div>
           <div className="setting">
diff --git a/src/mob/modalconfig/pastecomponent/index.jsx b/src/mob/modalconfig/pastecomponent/index.jsx
index 71df022..03b2200 100644
--- a/src/mob/modalconfig/pastecomponent/index.jsx
+++ b/src/mob/modalconfig/pastecomponent/index.jsx
@@ -34,13 +34,13 @@
       if (res.field && keys.includes(res.field.toLowerCase())) {
         notification.warning({
           top: 92,
-          message: '鎼滅储瀛楁宸插瓨鍦紒',
+          message: '瀛楁宸插瓨鍦紒',
           duration: 5
         })
         return
       }
 
-      this.props.updateConfig(config)
+      this.props.updateConfig({...config, fields: [...config.fields, res]})
       this.setState({visible: false})
 
       notification.success({
diff --git a/src/mob/searchconfig/controller.jsx b/src/mob/searchconfig/controller.jsx
index 10ae458..cd440c3 100644
--- a/src/mob/searchconfig/controller.jsx
+++ b/src/mob/searchconfig/controller.jsx
@@ -6,7 +6,6 @@
 
 class SearchController extends Component {
   state = {
-    btn: null,
     config: null,
     visible: false
   }
@@ -29,34 +28,33 @@
     MKEmitter.removeListener('changeSearch', this.initConfig)
   }
 
-  initConfig = (config, btn) => {
+  initConfig = (config) => {
     this.setState({
       visible: true,
-      config: fromJS(config).toJS(),
-      btn: fromJS(btn).toJS()
+      config: fromJS(config).toJS()
     })
   }
 
   handleBack = () => {
     this.setState({
       visible: false,
-      config: null,
-      btn: null
+      config: null
     })
   }
   
-  handleSave = (modal) => {
-    const { config, btn } = this.state
-    MKEmitter.emit('submitSearch', config, btn, modal)
+  handleSave = (search) => {
+    const { config } = this.state
+
+    MKEmitter.emit('submitSearch', {...config, search})
   }
 
   render () {
-    const { config, btn, visible } = this.state
+    const { config, visible } = this.state
 
     if (!visible) return null
 
     return (
-      <SearchConfig btn={btn} componentConfig={config} handleBack={this.handleBack} handleSave={this.handleSave}/>
+      <SearchConfig config={config.search} handleBack={this.handleBack} handleSave={this.handleSave}/>
     )
   }
 }
diff --git a/src/mob/searchconfig/groupdragelement/card.jsx b/src/mob/searchconfig/groupdragelement/card.jsx
new file mode 100644
index 0000000..b0e56e2
--- /dev/null
+++ b/src/mob/searchconfig/groupdragelement/card.jsx
@@ -0,0 +1,61 @@
+import React from 'react'
+import { useDrag, useDrop } from 'react-dnd'
+import { Icon, Popover } from 'antd'
+
+import './index.scss'
+
+const Card = ({ id, card, moveCard, findCard, editCard, closeCard, changeGroup }) => {
+  const originalIndex = findCard(id).index
+  const [{ isDragging }, drag] = useDrag({
+    item: { type: 'search', id, originalIndex },
+    collect: monitor => ({
+      isDragging: monitor.isDragging(),
+    }),
+  })
+  const [, drop] = useDrop({
+    accept: 'search',
+    canDrop: () => true,
+    drop: (item) => {
+      const { id: draggedId } = item
+
+      if (draggedId && draggedId !== id) {
+        const { index: overIndex } = findCard(id)
+        moveCard(draggedId, overIndex)
+      }
+    }
+  })
+  const opacity = isDragging ? 0 : 1
+
+  const edit = () => {
+    editCard(id)
+  }
+
+  const close = () => {
+    closeCard(id)
+  }
+
+  const change = () => {
+    changeGroup(id)
+  }
+
+  return (
+    <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+      <div className="mk-popover-control">
+        <Icon className="edit" type="edit" onClick={edit} />
+        <Icon className="close" type="close" onClick={close} />
+      </div>
+    } trigger="hover">
+      <div className="page-card" onDoubleClick={change} style={{ opacity: opacity}}>
+        <div ref={node => drag(drop(node))}>
+          {card.wrap.icon ? <div className="icon">
+            <Icon type={card.wrap.icon} />
+          </div> : null}
+          <div className="name">
+            {card.wrap.name}
+          </div>
+        </div>
+      </div>
+    </Popover>
+  )
+}
+export default Card
diff --git a/src/mob/searchconfig/groupdragelement/index.jsx b/src/mob/searchconfig/groupdragelement/index.jsx
new file mode 100644
index 0000000..da4ac2e
--- /dev/null
+++ b/src/mob/searchconfig/groupdragelement/index.jsx
@@ -0,0 +1,64 @@
+import React, { useState } from 'react'
+import { is, fromJS } from 'immutable'
+import update from 'immutability-helper'
+import Card from './card'
+import './index.scss'
+
+const Container = ({list, handleList, handleForm, closeForm, handleGroup }) => {
+  const [cards, setCards] = useState(list)
+  const moveCard = (id, atIndex) => {
+    const { card, index } = findCard(id)
+
+    if (!card) return
+
+    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
+
+    handleList(_cards)
+  }
+
+  if (!is(fromJS(cards), fromJS(list))) {
+    setCards(list)
+  }
+
+  const findCard = id => {
+    const card = cards.filter(c => `${c.uuid}` === id)[0]
+    return {
+      card,
+      index: cards.indexOf(card),
+    }
+  }
+
+  const editCard = id => {
+    const { card } = findCard(id)
+
+    handleForm(card)
+  }
+
+  const closeCard = id => {
+    const { card } = findCard(id)
+    closeForm(card)
+  }
+
+  const changeGroup = id => {
+    const { card } = findCard(id)
+    handleGroup(card)
+  }
+
+  return (
+    <div className="ant-row modal-search-groups-row">
+      {cards.map(card => {
+        return <Card
+          id={card.uuid}
+          key={card.uuid}
+          card={card}
+          moveCard={moveCard}
+          editCard={editCard}
+          closeCard={closeCard}
+          changeGroup={changeGroup}
+          findCard={findCard}
+        />
+      })}
+    </div>
+  )
+}
+export default Container
diff --git a/src/mob/searchconfig/groupdragelement/index.scss b/src/mob/searchconfig/groupdragelement/index.scss
new file mode 100644
index 0000000..068d8d6
--- /dev/null
+++ b/src/mob/searchconfig/groupdragelement/index.scss
@@ -0,0 +1,27 @@
+
+.modal-search-groups-row {
+  min-height: 20px!important;
+  padding-right: 30px;
+  margin-bottom: 15px;
+  .page-card {
+    float: left;
+    width: 13.333%;
+    text-align: center;
+    padding: 5px;
+    .icon {
+      background: #f0f0f0;
+      color: #000000;
+      border-radius: 30px;
+      width: 35px;
+      height: 35px;
+      line-height: 35px;
+      font-size: 18px;
+      margin: 0 auto 5px;
+    }
+    .name {
+      font-size: 13px;
+      white-space: nowrap;
+      color: rgba(0, 0, 0, 0.85);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/mob/searchconfig/groupform/index.jsx b/src/mob/searchconfig/groupform/index.jsx
new file mode 100644
index 0000000..44598bc
--- /dev/null
+++ b/src/mob/searchconfig/groupform/index.jsx
@@ -0,0 +1,90 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input } from 'antd'
+import { formRule } from '@/utils/option.js'
+import asyncComponent from '@/utils/asyncComponent'
+import './index.scss'
+
+const MkIcon = asyncComponent(() => import('@/components/mkIcon'))
+
+class SettingForm extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,     // 瀛楀吀椤�
+    config: PropTypes.object,   // 琛ㄥ崟閰嶇疆淇℃伅
+    inputSubmit: PropTypes.any  // 鍥炶溅鎻愪氦浜嬩欢
+  }
+
+  state = {}
+
+  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 { config } = this.props
+    const { getFieldDecorator } = this.props.form
+
+    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={22}>
+            <Form.Item label="鍚嶇О">
+              {getFieldDecorator('name', {
+                initialValue: config.wrap.name,
+                rules: [
+                  {
+                    required: true,
+                    message: '璇峰~鍐欏悕绉�!'
+                  },
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
+                  }
+                ]
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+          <Col span={22}>
+            <Form.Item label="鍥炬爣">
+              {getFieldDecorator('icon', {
+                initialValue: config.wrap.icon
+              })(
+                <MkIcon allowClear/>
+              )}
+            </Form.Item>
+          </Col>
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/mob/searchconfig/groupform/index.scss b/src/mob/searchconfig/groupform/index.scss
new file mode 100644
index 0000000..9a74987
--- /dev/null
+++ b/src/mob/searchconfig/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/mob/searchconfig/index.jsx b/src/mob/searchconfig/index.jsx
index 0f0ca45..89587cf 100644
--- a/src/mob/searchconfig/index.jsx
+++ b/src/mob/searchconfig/index.jsx
@@ -10,21 +10,20 @@
 import Utils from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
-import { getModalForm } from '@/templates/zshare/formconfig'
-
-import ModalForm from '@/templates/zshare/modalform'
+import { getSearchForm } from '@/templates/zshare/formconfig'
 import SourceElement from '@/templates/modalconfig/dragelement/source'
-import SettingForm from '@/templates/modalconfig/settingform'
+import SettingForm from './settingform'
 import asyncComponent from '@/utils/asyncComponent'
 import { SearchItems } from './source'
 import './index.scss'
 
 const { Panel } = Collapse
 const { confirm } = Modal
-const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+const SearchForm = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent/searchform'))
 const PasteComponent = asyncComponent(() => import('./pastecomponent'))
-const DragElement = asyncComponent(() => import('@/mob/components/formdragelement'))
-const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
+const DragElement = asyncComponent(() => import('./searchdragelement'))
+const GDragElement = asyncComponent(() => import('./groupdragelement'))
+const GroupForm = asyncComponent(() => import('./groupform'))
 
 class ComModalConfig extends Component {
   static propTpyes = {
@@ -34,7 +33,7 @@
   }
 
   state = {
-    dict: CommonDict,      // 瀛楀吀
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,      // 瀛楀吀
     config: null,          // 椤甸潰閰嶇疆锛屽寘鎷ā鏉跨被鍨嬨�佹ā鎬佹璁剧疆銆佹坊鍔犺〃鍚嶃�佽〃鍗曞垪琛�
     visible: false,        // 琛ㄥ崟缂栬緫妯℃�佹锛屾樉绀烘帶鍒�
     formlist: null,        // 琛ㄥ崟缂栬緫妯℃�佹锛屽彲缂栬緫瀛楁
@@ -43,21 +42,20 @@
     originConfig: null,    // 鍘熷鑿滃崟
     sqlVerifing: false,    // sql楠岃瘉
     showField: false,      // 鏄剧ず琛ㄥ崟瀛楁鍊�
-    standardform: null
+    group: null,
+    editGroup: null
   }
 
   /**
    * @description 鏁版嵁棰勫鐞�
    */
   UNSAFE_componentWillMount () {
-    const { btn } = this.props
-
-    let _config = btn.modal
-    _config.version = '1.0'
+    const { config } = this.props
 
     this.setState({
-      config: _config,
-      originConfig: fromJS(_config).toJS()
+      group: fromJS(config).toJS(),
+      config: fromJS(config).toJS(),
+      originConfig: fromJS(config).toJS()
     })
   }
 
@@ -72,105 +70,74 @@
 
   /**
    * @description 琛ㄥ崟鍙樺寲
-   * 1銆佽〃鍗曟嫋鎷芥坊鍔犳椂锛屾鏌ユ槸鍚﹀瓨鍦ㄧず渚嬭〃鍗曪紝濡傚瓨鍦ㄥ垯鍘婚櫎绀轰緥
-   * 2銆佽〃鍗曠Щ鍔ㄥ悗锛屼繚瀛樼Щ鍔ㄥ悗鐨勯『搴�
-   * 3銆佹柊澧炶〃鍗曟椂锛岀洿鎺ユ墦寮�缂栬緫妗�
    */
   handleList = (list, newcard) => {
-    let _config = fromJS(this.state.config).toJS()
+    let _group = {...this.state.group, fields: list}
 
-    if (list.length > _config.fields.length) {
-      _config.fields = list.filter(item => !item.origin)
-
-      this.setState({
-        config: _config
-      }, () => {
+    this.setState({
+      group: _group
+    }, () => {
+      if (newcard) {
         this.handleForm(newcard)
-      })
+      }
+    })
+    this.resetConfig(_group)
+  }
+
+  /**
+   * @description 鍒嗙粍鍙樺寲
+   */
+  handleGroupList = (list) => {
+    let _group = {...this.state.group, groups: list}
+
+    this.setState({
+      group: _group
+    })
+    this.resetConfig(_group)
+  }
+
+  /**
+   * @description 琛ㄥ崟鍙樺寲
+   */
+  handleList = (list, newcard) => {
+    let _group = {...this.state.group, fields: list}
+
+    this.setState({
+      group: _group
+    }, () => {
+      if (newcard) {
+        this.handleForm(newcard)
+      }
+    })
+    this.resetConfig(_group)
+  }
+
+  resetConfig = (group) => {
+    let _config = fromJS(this.state.config).toJS()
+    if (group.floor === 1) {
+      _config = group
     } else {
-      _config.fields = list
-      this.setState({config: _config})
+      _config.groups = _config.groups.map(item => {
+        if (item.uuid === group.uuid) return group
+        return item
+      })
     }
+
+    this.setState({
+      config: _config
+    })
   }
 
   /**
    * @description 琛ㄥ崟缂栬緫
-   * 1銆佹樉绀虹紪杈戝脊绐�-visible
-   * 2銆佷繚瀛樼紪杈戦」-card
-   * 3銆佽缃紪杈戝弬鏁伴」-formlist
    */
   handleForm = (_card) => {
-    const { componentConfig } = this.props
-    const { config } = this.state
     let card = fromJS(_card).toJS()
-    let _inputfields = []
-    let _tabfields = []
-    let _linkableFields = []
-    let _linksupFields = [{
-      value: '',
-      text: '绌�'
-    }]
-    let standardform = null
-
-    _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
-    _tabfields = config.fields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
-    _tabfields.unshift({field: '', text: '鍘熻〃鍗�'})
-
-    let uniq = new Map()
-    uniq.set(card.field, true)
-    let index = null
-    config.fields.forEach((item, i) => {
-      if (card.uuid === item.uuid) {
-        index = i
-      }
-      if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') 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 = config.fields[index + 1] || null
-      } else {
-        standardform = config.fields[index - 1] || null
-      }
-    }
-
-    componentConfig.columns.forEach(col => {
-      if (col.field && !uniq.has(col.field)) {
-        uniq.set(col.field, true)
-
-        _linkableFields.push({
-          value: col.field,
-          text: col.label + ' (鏄剧ず鍒�)'
-        })
-      }
-    })
-
-    if (card.linkSubField && card.linkSubField.length > 0) {
-      let fields = _inputfields.map(item => item.field)
-      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
-    }
-
-    if (!card.span && standardform && standardform.span) {
-      card.span = standardform.span
-      card.labelwidth = standardform.labelwidth
-    }
 
     this.setState({
-      standardform,
       visible: true,
       card: card,
-      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, !!this.props.editTab)
+      formlist: getSearchForm(card, [])
     })
   }
 
@@ -182,15 +149,12 @@
    */
   handleSubmit = () => {
     this.formRef.handleConfirm().then(res => {
-      let _config = fromJS(this.state.config).toJS()
+      let _group = 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()) {
+      _group.fields = _group.fields.map(item => {
+        if (item.uuid !== res.uuid && 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) {
@@ -207,18 +171,9 @@
           duration: 10
         })
         return
-      } else if (labelrepet) {
-        notification.warning({
-          top: 92,
-          message: '鍚嶇О宸插瓨鍦紒',
-          duration: 10
-        })
-        return
       }
 
-      _config.fields = _config.fields.filter(item => !item.origin)
-
-      if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+      if (['checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
         this.setState({
           sqlVerifing: true
         })
@@ -243,10 +198,11 @@
           if (result.status) {
             this.setState({
               sqlVerifing: false,
-              config: _config,
+              group: _group,
               card: null,
               visible: false
             })
+            this.resetConfig(_group)
           } else {
             this.setState({sqlVerifing: false})
             
@@ -257,10 +213,11 @@
         })
       } else {
         this.setState({
-          config: _config,
+          group: _group,
           card: null,
           visible: false
         })
+        this.resetConfig(_group)
       }
     })
   }
@@ -274,12 +231,13 @@
     confirm({
       content: `纭畾鍒犻櫎${card.label ? `<<${card.label}>>` : ''}鍚楋紵`,
       onOk() {
-        let _config = fromJS(_this.state.config).toJS()
-        _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
+        let _group = fromJS(_this.state.group).toJS()
+        _group.fields = _group.fields.filter(item => item.uuid !== card.uuid)
 
         _this.setState({
-          config: _config,
+          group: _group,
         })
+        _this.resetConfig(_group)
       },
       onCancel() {}
     })
@@ -315,7 +273,7 @@
   }
 
   /**
-   * @description 鍏ㄥ眬璁剧疆妯℃�佹
+   * @description 鍒嗙粍璁剧疆妯℃�佹
    */
   changeSetting = () => {
     this.setState({
@@ -324,30 +282,32 @@
   }
 
   /**
-   * @description 淇濆瓨鍏ㄥ眬璁剧疆
+   * @description 淇濆瓨鍒嗙粍璁剧疆
    */
   settingSave = () => {
-    const {config} = this.state
     this.settingRef.handleConfirm().then(res => {
+      let _group = {...this.state.group, setting: res}
       this.setState({
-        config: {...config, setting: res},
+        group: _group,
         settingVisible: false
       })
+      this.resetConfig(_group)
     })
   }
 
   editModalCancel = () => {
-    const { config, card } = this.state
+    const { group, card } = this.state
 
     if (card.focus) {
-      let _fields = config.fields.filter(item => item.uuid !== card.uuid)
-      let _config = {...config, fields: _fields}
+      let _fields = group.fields.filter(item => item.uuid !== card.uuid)
+      let _group = {...group, fields: _fields}
 
       this.setState({
         card: null,
-        config: _config,
+        group: _group,
         visible: false
       })
+      this.resetConfig(_group)
     } else {
       this.setState({
         card: null,
@@ -356,18 +316,77 @@
     }
   }
 
-  /**
-   * @description 鏇存柊
+  plusGroup = () => {
+    let config = fromJS(this.state.config).toJS()
+    let _g = {
+      uuid: Utils.getuuid(),
+      wrap: { name: 'name', icon: '' },
+      setting: { type: 'title', field: '', title: '', focus: 'true', btn: 'hidden' },
+      fields: []
+    }
+
+    config.groups.push(_g)
+
+    this.setState({config, group: config, editGroup: _g, gVisible: true})
+  }
+
+  handleGroupForm = (_g) => {
+    this.setState({editGroup: _g, gVisible: true})
+  }
+
+   /**
+   * @description 淇濆瓨鍒嗙粍璁剧疆
    */
-  updateConfig = (config) => {
+  groupSave = () => {
+    this.gRef.handleConfirm().then(res => {
+      let _g = {...this.state.editGroup, wrap: res}
+
+      let _group = fromJS(this.state.group).toJS()
+      _group.groups = _group.groups.map(item => {
+        if (item.uuid === _g.uuid) return _g
+        return item
+      })
+
+      this.setState({
+        editGroup: null,
+        group: _group,
+        gVisible: false
+      })
+      this.resetConfig(_group)
+    })
+  }
+
+  handleGroup = (g) => {
     this.setState({
-      config
+      group: g
+    })
+  }
+
+  closeGroup = (g) => {
+    const _this = this
+    let _group = fromJS(this.state.group).toJS()
+    _group.groups = _group.groups.filter(item => item.uuid !== g.uuid)
+
+    confirm({
+      content: `纭畾鍒犻櫎鍒嗙粍銆�${g.wrap.name}銆嬪悧锛焋,
+      onOk() {
+        _this.setState({ group: _group })
+        _this.resetConfig(_group)
+      },
+      onCancel() {}
+    })
+  }
+
+  returnUp = () => {
+    const { config } = this.state
+
+    this.setState({
+      group: config
     })
   }
 
   render () {
-    const { config, dict } = this.state
-
+    const { dict, group, editGroup } = this.state
     return (
       <div className="mob-search-board">
         <DndProvider backend={HTML5Backend}>
@@ -379,38 +398,48 @@
                     return (<SourceElement key={index} content={item}/>)
                   })}
                 </div>
-                <FieldsComponent
-                  config={config}
-                  type="form"
-                  updatefield={this.updateConfig}
-                />
               </Panel>
             </Collapse>
           </div>
           <div className="modal-control">
-            <Button icon="setting" onClick={this.changeSetting}>璁剧疆</Button>
             <Button type="primary" onClick={this.submitConfig}>淇濆瓨</Button>
-            <Button onClick={this.cancelConfig}>杩斿洖</Button>
-            <PasteComponent type="menu" Tab={null} insert={this.insert} />
+            <Button onClick={this.cancelConfig}>鍏抽棴</Button>
+            {!group.floor ? <Button onClick={this.returnUp}>杩斿洖涓婄骇</Button> : null}
+            <PasteComponent insert={this.insert} />
             <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
           </div>
           <div className="setting">
             <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
               <div className="mob-shell-inner">
-                <div className="am-navbar">
+                <Icon className="setting-group" onClick={this.changeSetting} type="setting" />
+                {group.setting.type === 'title' ? <div className="am-navbar">
                   <Icon type="close" />
-                  <div className="am-navbar-title">{config.setting.title}</div>
+                  <div className="am-navbar-title">{group.setting.title}</div>
+                </div> : <div className="am-navbar">
+                  <Icon type="left" />
+                  <div className="search-bar"><Icon type="search" /></div>
+                </div>}
+                {group.floor === 1 ? <Icon className="plus-group" type="plus" onClick={this.plusGroup} /> : null}
+                <div style={{minHeight: 'calc(100% - 100px)'}}>
+                  {group.floor === 1 && group.groups.length > 0 ? <GDragElement
+                    list={group.groups}
+                    handleList={this.handleGroupList}
+                    handleForm={this.handleGroupForm}
+                    handleGroup={this.handleGroup}
+                    closeForm={this.closeGroup}
+                  /> : null}
+                  <DragElement
+                    list={group.fields}
+                    showField={this.state.showField}
+                    handleList={this.handleList}
+                    handleForm={this.handleForm}
+                    closeForm={this.closeForm}
+                  />
                 </div>
-                <DragElement
-                  list={config.fields}
-                  setting={config.setting}
-                  showField={this.state.showField}
-                  placeholder={this.state.dict['header.form.modal.placeholder']}
-                  handleList={this.handleList}
-                  handleForm={this.handleForm}
-                  closeForm={this.closeForm}
-                />
-                <Button className="modal-submit" type="primary">纭畾</Button>
+                {group.setting.btn !== 'hidden' ? <div className="search-btn">
+                  <Button className="reset">閲嶇疆</Button>
+                  <Button className="submit" type="primary">纭畾</Button>
+                </div> : null}
               </div>
             </div>
           </div>
@@ -424,12 +453,11 @@
           confirmLoading={this.state.sqlVerifing}
           destroyOnClose
         >
-          <ModalForm
+          <SearchForm
             dict={this.state.dict}
             card={this.state.card}
             formlist={this.state.formlist}
             inputSubmit={this.handleSubmit}
-            standardform={this.state.standardform}
             wrappedComponentRef={(inst) => this.formRef = inst}
           />
         </Modal>
@@ -443,13 +471,26 @@
           destroyOnClose
         >
           <SettingForm
-            config={config}
-            dict={this.state.dict}
-            isSubTab={!!this.props.editTab}
+            config={group}
             inputSubmit={this.settingSave}
             wrappedComponentRef={(inst) => this.settingRef = inst}
           />
         </Modal>
+        <Modal
+          title={this.state.dict['model.edit']}
+          visible={this.state.gVisible}
+          width={600}
+          maskClosable={false}
+          onOk={this.groupSave}
+          onCancel={() => { this.setState({ gVisible: false }) }}
+          destroyOnClose
+        >
+          <GroupForm
+            config={editGroup}
+            inputSubmit={this.groupSave}
+            wrappedComponentRef={(inst) => this.gRef = inst}
+          />
+        </Modal>
       </div>
     )
   }
diff --git a/src/mob/searchconfig/index.scss b/src/mob/searchconfig/index.scss
index 662ace1..fac4043 100644
--- a/src/mob/searchconfig/index.scss
+++ b/src/mob/searchconfig/index.scss
@@ -156,28 +156,72 @@
         position: relative;
         border-bottom: 1px solid #f0f0f0;
         margin-bottom: 10px;
-        .anticon-close {
+        .anticon-close, .anticon-left {
           position: absolute;
           line-height: 45px;
           font-size: 18px;
-          right: 10px;
+          left: 10px;
         }
         .am-navbar-title {
           font-size: 16px;
           text-align: center;
+          color: #000000;
+        }
+        .search-bar {
+          height: 35px;
+          line-height: 35px;
+          padding: 0 10px;
+          color:rgba(0, 0, 0, 0.65);
+          border: 1px solid #E9EDF0;
+          background: #E9EDF0;
+          border-radius: 4px;
+          position: relative;
+          top: 50%;
+          transform: translateY(-50%);
+          margin: 0 30px 0 35px;
         }
       }
-      .modal-submit {
-        width: 100%;
-        border-radius: 0;
-        opacity: 0.5;
-        cursor: default;
-        font-size: 18px;
-        height: 40px;
+      .search-btn {
+        .reset {
+          width: 30%;
+          border-radius: 0;
+          opacity: 0.5;
+          cursor: default;
+          font-size: 18px;
+          height: 45px;
+        }
+        .submit {
+          width: 70%;
+          border-radius: 0;
+          opacity: 0.5;
+          cursor: default;
+          font-size: 18px;
+          height: 45px;
+        }
       }
 
-      .modal-fields-row {
-        min-height: calc(100% - 95px);
+      .setting-group {
+        position: absolute;
+        right: 0px;
+        top: 0px;
+        font-size: 18px;
+        padding: 5px;
+        cursor: pointer;
+        z-index: 1;
+      }
+      .plus-group {
+        color: #26C281;
+        position: absolute;
+        right: 0px;
+        top: 45px;
+        font-size: 18px;
+        padding: 5px;
+        cursor: pointer;
+        z-index: 2;
+      }
+
+      .modal-search-fields-row {
+        min-height: 300px;
         padding: 0 10px 35px;
       }
 
diff --git a/src/mob/searchconfig/pastecomponent/index.jsx b/src/mob/searchconfig/pastecomponent/index.jsx
index 71df022..ed81117 100644
--- a/src/mob/searchconfig/pastecomponent/index.jsx
+++ b/src/mob/searchconfig/pastecomponent/index.jsx
@@ -9,7 +9,6 @@
 
 class PasteController extends Component {
   static propTpyes = {
-    config: PropTypes.object,        // 缁勪欢閰嶇疆
     updateConfig: PropTypes.func
   }
 
@@ -18,36 +17,18 @@
   }
 
   pasteSubmit = () => {
-    const { config } = this.props
     this.pasteFormRef.handleConfirm().then(res => {
-      if (res.copyType !== 'form') {
+      if (res.copyType !== 'search') {
         notification.warning({ top: 92, message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�', duration: 5 })
         return
       }
-
-      let keys = config.fields.map(item => item.field ? item.field.toLowerCase() : '$emp_ty$')
 
       if (['multiselect', 'color', 'brafteditor'].includes(res.type)) {
         res.type = 'text'
       }
 
-      if (res.field && keys.includes(res.field.toLowerCase())) {
-        notification.warning({
-          top: 92,
-          message: '鎼滅储瀛楁宸插瓨鍦紒',
-          duration: 5
-        })
-        return
-      }
-
-      this.props.updateConfig(config)
+      this.props.updateConfig(res)
       this.setState({visible: false})
-
-      notification.success({
-        top: 92,
-        message: '绮樿创鎴愬姛锛�',
-        duration: 2
-      })
     })
   }
 
diff --git a/src/mob/searchconfig/searchdragelement/card.jsx b/src/mob/searchconfig/searchdragelement/card.jsx
new file mode 100644
index 0000000..5a4b632
--- /dev/null
+++ b/src/mob/searchconfig/searchdragelement/card.jsx
@@ -0,0 +1,132 @@
+import React from 'react'
+import { useDrag, useDrop } from 'react-dnd'
+import { Icon, Popover, Form } from 'antd'
+import { Range } from 'antd-mobile'
+import moment from 'moment'
+
+import asyncComponent from '@/utils/asyncComponent'
+import './index.scss'
+
+const CheckCard = asyncComponent(() => import('@/templates/modalconfig/checkCard'))
+
+const Card = ({ id, card, moveCard, findCard, editCard, closeCard, copyCard, showField }) => {
+  const originalIndex = findCard(id).index
+  const [{ isDragging }, drag] = useDrag({
+    item: { type: 'search', id, originalIndex },
+    collect: monitor => ({
+      isDragging: monitor.isDragging(),
+    }),
+  })
+  const [, drop] = useDrop({
+    accept: 'search',
+    canDrop: () => true,
+    drop: (item) => {
+      const { id: draggedId, originalIndex } = item
+
+      if (originalIndex === undefined) {
+        item.dropTargetId = id
+      } else if (draggedId && draggedId !== id) {
+        const { index: overIndex } = findCard(id)
+        moveCard(draggedId, overIndex)
+      }
+    }
+  })
+  const opacity = isDragging ? 0 : 1
+
+  const edit = () => {
+    editCard(id)
+  }
+
+  const close = () => {
+    closeCard(id)
+  }
+
+  const copy = () => {
+    copyCard(id)
+  }
+
+  let formItem = null
+  if (card.type === 'date') {
+    formItem = (<div className="am-list-item">
+      <div className="am-list-line">
+        {card.labelShow !== 'false' ? <div className="am-input-label">{card.label}</div> : null}
+        <div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'days').format('YYYY-MM-DD') : '璇烽�夋嫨'}</div>
+        <div className="am-list-extra"><Icon type="right" /></div>
+      </div>
+    </div>)
+  } else if (card.type === 'datemonth') {
+    formItem = (<div className="am-list-item">
+      <div className="am-list-line">
+        {card.labelShow !== 'false' ? <div className="am-input-label">{card.label}</div> : null}
+        <div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'month').format('YYYY-MM') : '璇烽�夋嫨'}</div>
+        <div className="am-list-extra"><Icon type="right" /></div>
+      </div>
+    </div>)
+  } else if (card.type === 'range') {
+    let value = [(card.minValue || 0), (card.maxValue || 20)]
+    if (card.initval) {
+      value = card.initval.split(',')
+      value = [+value[0], +value[1]]
+    }
+    formItem = (<div className="am-list-item slider">
+      <div className="am-list-line">
+        {card.labelShow !== 'false' ? <div className="am-input-label">{card.label}</div> : null}
+        <div className="am-input-control">
+          <Range
+            min={card.minValue || 0}
+            max={card.maxValue || 20}
+            value={value}
+          />
+        </div>
+      </div>
+    </div>)
+  } else if (card.type === 'daterange') {
+    let value = '璇烽�夋嫨'
+    if (card.initval) {
+      try {
+        let _initval = JSON.parse(card.initval)
+        value = [moment().subtract(_initval[0], 'days').format('YYYY-MM-DD'), moment().subtract(_initval[1], 'days').format('YYYY-MM-DD')].join(' ~ ')
+      } catch {
+        value = '璇烽�夋嫨'
+      }
+    }
+    formItem = (<div className="am-list-item">
+      <div className="am-list-line">
+        {card.labelShow !== 'false' ? <div className="am-input-label">{card.label}</div> : null}
+        <div className="am-input-control">{value}</div>
+        <div className="am-list-extra"><Icon type="right" /></div>
+      </div>
+    </div>)
+  } else if (card.type === 'checkcard') {
+    formItem = (<div className="am-list-item check-card">
+      <div className="am-list-line">
+        {card.labelShow !== 'false' ? <div className="am-input-label">{card.label}</div> : null}
+        <div className="am-input-control">
+          <CheckCard config={card} />
+        </div>
+      </div>
+    </div>)
+  }
+
+  return (
+    <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+      <div className="mk-popover-control">
+        <Icon className="edit" type="edit" onClick={edit} />
+        <Icon className="copy" type="copy" onClick={copy} />
+        <Icon className="close" type="close" onClick={close} />
+      </div>
+    } trigger="hover">
+      <div className="page-card" style={{ opacity: opacity}}>
+        <div ref={node => drag(drop(node))}>
+          {card.type === 'split' ? formItem : <Form.Item
+            className={'ant-form-item' + (card.required === 'true' ? ' required' : '') + (card.splitline === 'false' ? ' no-boder' : '')}
+          >
+            {formItem}
+            {showField ? <div className="field-name">{card.field}{card.hidden === 'true' ? '(闅愯棌)' : ''}</div> : ''}
+          </Form.Item>}
+        </div>
+      </div>
+    </Popover>
+  )
+}
+export default Card
diff --git a/src/mob/searchconfig/searchdragelement/index.jsx b/src/mob/searchconfig/searchdragelement/index.jsx
new file mode 100644
index 0000000..10a535e
--- /dev/null
+++ b/src/mob/searchconfig/searchdragelement/index.jsx
@@ -0,0 +1,123 @@
+import React, { useState } from 'react'
+import { useDrop } from 'react-dnd'
+import { is, fromJS } from 'immutable'
+import update from 'immutability-helper'
+import Utils from '@/utils/utils.js'
+import Card from './card'
+import './index.scss'
+
+const Container = ({list, handleList, handleForm, closeForm, showField }) => {
+  const [cards, setCards] = useState(list)
+  const moveCard = (id, atIndex) => {
+    const { card, index } = findCard(id)
+
+    if (!card) return
+
+    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
+
+    handleList(_cards)
+  }
+
+  if (!is(fromJS(cards), fromJS(list))) {
+    setCards(list)
+  }
+
+  const findCard = id => {
+    const card = cards.filter(c => `${c.uuid}` === id)[0]
+    return {
+      card,
+      index: cards.indexOf(card),
+    }
+  }
+
+  const editCard = id => {
+    const { card } = findCard(id)
+    delete card.focus
+    handleForm(card)
+  }
+
+  const closeCard = id => {
+    const { card } = findCard(id)
+    closeForm(card)
+  }
+
+  const copyCard = id => {
+    const { card, index: overIndex } = findCard(id)
+
+    let _card = fromJS(card).toJS()
+    _card.uuid = Utils.getuuid()
+    _card.focus = true
+
+    // 澶嶅埗鍒板壀鍒囨澘
+    let oInput = document.createElement('input')
+    let val = JSON.parse(JSON.stringify(_card))
+    val.copyType = 'search'
+
+    oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val)))
+    document.body.appendChild(oInput)
+    oInput.select()
+    document.execCommand('Copy')
+    oInput.className = 'oInput'
+    oInput.style.display = 'none'
+    document.body.removeChild(oInput)
+
+    const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
+
+    setCards(_cards)
+
+    handleList(_cards, _card)
+  }
+
+  const [, drop] = useDrop({
+    accept: 'search',
+    drop(item) {
+      if (item.hasOwnProperty('originalIndex')) {
+        return
+      }
+
+      let newcard = {}
+      newcard.uuid = Utils.getuuid()
+      newcard.label = 'label'
+      newcard.type = item.subType
+      newcard.resourceType = '0'
+      newcard.options = []
+      newcard.required = 'true'
+      newcard.focus = true
+
+      let targetId = ''
+
+      if (item.dropTargetId) {
+        targetId = item.dropTargetId
+        delete item.dropTargetId
+      } else if (cards.length > 0) {
+        targetId = cards[cards.length - 1].uuid
+      }
+
+      const { index: overIndex } = findCard(`${targetId}`) // cards涓虹┖鏃� overIndex 涓� -1
+      const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] })
+
+      setCards(_cards)
+
+      handleList(_cards, newcard)
+    }
+  })
+
+  return (
+    <div ref={drop} className="ant-row modal-search-fields-row">
+      {cards.map(card => {
+        return <Card
+          id={card.uuid}
+          key={card.uuid}
+          card={card}
+          showField={showField}
+          moveCard={moveCard}
+          editCard={editCard}
+          closeCard={closeCard}
+          copyCard={copyCard}
+          findCard={findCard}
+        />
+      })}
+    </div>
+  )
+}
+export default Container
diff --git a/src/mob/searchconfig/searchdragelement/index.scss b/src/mob/searchconfig/searchdragelement/index.scss
new file mode 100644
index 0000000..113604d
--- /dev/null
+++ b/src/mob/searchconfig/searchdragelement/index.scss
@@ -0,0 +1,148 @@
+
+.modal-search-fields-row {
+  padding-bottom: 35px;
+  .mob-col.ant-col {
+    display: inline-block;
+    float: none;
+    vertical-align: top;
+    padding-left: 1.2%;
+    padding-right: 1.2%;
+  }
+  .am-list-item {
+    font-size: 16px;
+    padding-left: 10px;
+    position: relative;
+    display: flex;
+    height: 44px;
+    min-height: 44px;
+    background-color: #fff;
+    vertical-align: middle;
+    overflow: hidden;
+    transition: background-color 200ms;
+    align-items: center;
+
+    .am-list-line {
+      align-items: center;
+      position: relative;
+      display: flex;
+      flex: 1 1;
+      align-self: stretch;
+      padding-right: 15px;
+      overflow: hidden;
+      .am-input-label {
+        width: 28%;
+        color: #000;
+        font-size: 16px;
+        margin-left: 0;
+        margin-right: 5px;
+        text-align: left;
+        white-space: nowrap;
+        overflow: hidden;
+        padding: 2px 0;
+        text-overflow: ellipsis;
+      }
+      .am-list-switch {
+        flex: 1;
+        text-align: right;
+      }
+      .am-input-control {
+        font-size: 16px;
+        flex: 1 1;
+        text-align: right;
+      }
+      .am-input-control.left {
+        text-align: left;
+      }
+      .am-list-extra {
+        display: block;
+        width: 15px;
+        height: 15px;
+        margin-left: 8px;
+        i {
+          vertical-align: top;
+        }
+      }
+    }
+  }
+  .am-list-item.check-card {
+    height: auto;
+    .am-list-line {
+      align-items: start;
+      display: block;
+      .check-card-edit-box {
+        margin-top: 0!important;
+      }
+    }
+  }
+  .am-list-item.hint {
+    height: auto;
+    .am-list-line {
+      align-items: start;
+      display: block;
+      .am-input-label {
+        line-height: 2;
+      }
+      .am-input-control {
+        font-size: 14px;
+        line-height: 1.5;
+        text-align: left;
+        padding-bottom: 5px;
+      }
+    }
+  }
+  .am-list-item.slider {
+    height: auto;
+    .am-list-line {
+      align-items: start;
+      display: block;
+      .am-input-control {
+        height: 25px;
+        padding-top: 10px;
+      }
+    }
+  }
+  
+  .check-card-edit-box .card-cell span {
+    line-height: 1.5;
+  }
+  .ant-form-item {
+    cursor: move;
+    margin-bottom: 0px;
+    .ant-form-item-control-wrapper::after {
+      content: '';
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      opacity: 0;
+      z-index: 1;
+    }
+    .field-name {
+      margin-left: 10px;
+      line-height: 1.5;
+    }
+    .ant-form-item-children {
+      vertical-align: top;
+    }
+  }
+  .ant-form-item.required {
+    .am-input-label::before {
+      display: inline-block;
+      margin-right: 4px;
+      color: #f5222d;
+      font-size: 14px;
+      font-family: SimSun, sans-serif;
+      line-height: 1;
+      content: '*';
+    }
+  }
+  .ant-form-item.no-boder {
+    .am-list-line {
+      border-bottom: none;
+    }
+  }
+  .page-card {
+    margin-bottom: 10px;
+  }
+}
\ No newline at end of file
diff --git a/src/mob/searchconfig/settingform/index.jsx b/src/mob/searchconfig/settingform/index.jsx
new file mode 100644
index 0000000..29099e7
--- /dev/null
+++ b/src/mob/searchconfig/settingform/index.jsx
@@ -0,0 +1,192 @@
+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,     // 瀛楀吀椤�
+    config: PropTypes.object,   // 琛ㄥ崟閰嶇疆淇℃伅
+    inputSubmit: PropTypes.any  // 鍥炶溅鎻愪氦浜嬩欢
+  }
+
+  state = {
+    roleList: [],
+    type: this.props.config.setting.type || 'title'
+  }
+
+  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 { config } = this.props
+    const { getFieldDecorator } = this.props.form
+    const { type, roleList } = 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('type', {
+                initialValue: type
+              })(
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({type: e.target.value})}>
+                  <Radio value="title">鏍囬鏍�</Radio>
+                  <Radio value="search">鎼滅储鏍�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {type === 'title' ? <Col span={12}>
+            <Form.Item label="鏍囬">
+              {getFieldDecorator('title', {
+                initialValue: config.setting.title,
+                rules: [
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
+                  }
+                ]
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col> : null}
+          {type === 'search' ? <Col span={12}>
+            <Form.Item label="鎼滅储瀛楁">
+              {getFieldDecorator('field', {
+                initialValue: config.setting.field,
+                rules: [
+                  {
+                    required: true,
+                    message: '璇峰~鍐欏瓧娈�!'
+                  },
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
+                  },
+                  {
+                    pattern: formRule.field.multipattern,
+                    message: formRule.field.message
+                  }
+                ]
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col> : null}
+          {type === 'search' ? <Col span={12}>
+            <Form.Item label="鍒濆鍊�">
+              {getFieldDecorator('initval', {
+                initialValue: config.setting.initval,
+                rules: [
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
+                  }
+                ]
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col> : null}
+          {type === 'search' ? <Col span={12}>
+            <Form.Item label="蹇呭~">
+              {getFieldDecorator('required', {
+                initialValue: config.setting.required || 'false'
+              })(
+                <Radio.Group>
+                  <Radio value="true">鏄�</Radio>
+                  <Radio value="false">鍚�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
+          {type === 'search' ? <Col span={12}>
+            <Form.Item label="鑷姩鑱氱劍">
+              {getFieldDecorator('focus', {
+                initialValue: config.setting.focus || 'true'
+              })(
+                <Radio.Group>
+                  <Radio value="true">鏄�</Radio>
+                  <Radio value="false">鍚�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
+          <Col span={12}>
+            <Form.Item label="鎼滅储鎸夐挳">
+              {getFieldDecorator('btn', {
+                initialValue: config.setting.btn || 'hidden'
+              })(
+                <Radio.Group>
+                  <Radio value="hidden">闅愯棌</Radio>
+                  <Radio value="show">鏄剧ず</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {type === 'search' ? <Col span={12}>
+            <Form.Item label="榛戝悕鍗�">
+              {getFieldDecorator('blacklist', {
+                initialValue: config.setting.blacklist || []
+              })(
+                <Select
+                  showSearch
+                  mode="multiple"
+                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                >
+                  {roleList.map(option =>
+                    <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col> : null}
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/mob/searchconfig/settingform/index.scss b/src/mob/searchconfig/settingform/index.scss
new file mode 100644
index 0000000..9a74987
--- /dev/null
+++ b/src/mob/searchconfig/settingform/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/mob/searchconfig/source.jsx b/src/mob/searchconfig/source.jsx
index 3fed414..9d4684f 100644
--- a/src/mob/searchconfig/source.jsx
+++ b/src/mob/searchconfig/source.jsx
@@ -1,104 +1,33 @@
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-
-const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
-
 export const SearchItems = [
   {
-    type: 'form',
-    label: CommonDict['model.form.text'],
-    subType: 'text',
+    type: 'search',
+    label: '鏁板�硷紙鍖洪棿锛�',
+    subType: 'range',
     url: ''
   },
   {
-    type: 'form',
-    label: CommonDict['model.form.number'],
-    subType: 'number',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: CommonDict['model.form.select'],
-    subType: 'select',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: CommonDict['model.form.link'],
-    subType: 'link',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: '寮�鍏�',
-    subType: 'switch',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: '澶氶�夋',
-    subType: 'checkbox',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: '鍗曢�夋',
-    subType: 'radio',
-    url: ''
-  },
-  {
-    type: 'form',
+    type: 'search',
     label: '閫夐」鍗�',
     subType: 'checkcard',
     url: ''
   },
   {
-    type: 'form',
-    label: CommonDict['header.form.fileupload'],
-    subType: 'fileupload',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: CommonDict['model.form.dateday'],
+    type: 'search',
+    label: '鏃ユ湡锛堝ぉ锛�',
     subType: 'date',
     url: ''
   },
   {
-    type: 'form',
-    label: CommonDict['model.form.datemonth'],
+    type: 'search',
+    label: '鏃ユ湡锛堟湀锛�',
     subType: 'datemonth',
     url: ''
   },
   {
-    type: 'form',
-    label: CommonDict['model.form.datetime'],
-    subType: 'datetime',
+    type: 'search',
+    label: '鏃ユ湡锛堝尯闂达級',
+    subType: 'daterange',
     url: ''
   },
-  {
-    type: 'form',
-    label: CommonDict['model.form.textarea'],
-    subType: 'textarea',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: CommonDict['header.form.funcvar'],
-    subType: 'funcvar',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: '鎻愮ず',
-    subType: 'hint',
-    url: ''
-  },
-  {
-    type: 'form',
-    label: '鍒嗗壊绾�',
-    subType: 'split',
-    url: ''
-  }
 ]
 
diff --git a/src/templates/formtabconfig/index.jsx b/src/templates/formtabconfig/index.jsx
index 47db6ac..c5bca12 100644
--- a/src/templates/formtabconfig/index.jsx
+++ b/src/templates/formtabconfig/index.jsx
@@ -16,23 +16,25 @@
 
 import TabsComponent from '@/templates/sharecomponent/tabscomponent'
 
-import ModalForm from '@/templates/zshare/modalform'
 import PasteForm from '@/templates/zshare/pasteform'
 import ActionForm from './actionform'
 import SettingForm from './settingform'
 import DragElement from './dragelement'
 import GroupForm from './groupform'
 import EditCard from '@/templates/zshare/editcard'
-import VerifyCard from '@/templates/zshare/verifycard'
+
 import MenuForm from '@/templates/zshare/menuform'
 import SourceElement from '@/templates/zshare/dragsource'
-import CreateFunc from '@/templates/zshare/createfunc'
+import asyncComponent from '@/utils/asyncComponent'
 import Source from './source'
 import './index.scss'
 
 const { Panel } = Collapse
 const { Option } = Select
 const { confirm } = Modal
+const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
+const CreateFunc = asyncComponent(() => import('@/templates/zshare/createfunc'))
+const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard'))
 
 class ComTableConfig extends Component {
   static propTpyes = {
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index 68417e4..6c1a14a 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -13,7 +13,6 @@
 import enUS from '@/locales/en-US/model.js'
 import { getModalForm } from '@/templates/zshare/formconfig'
 
-import ModalForm from '@/templates/zshare/modalform'
 import SourceElement from './dragelement/source'
 import SettingForm from './settingform'
 import MenuForm from './menuform'
@@ -25,6 +24,7 @@
 const { Panel } = Collapse
 const { confirm } = Modal
 const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
 const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
 const DragElement = asyncComponent(() => import('./dragelement'))
 const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index af2d93c..dac14ca 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -96,7 +96,8 @@
   dateweek: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced'],
   datemonth: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced'],
   daterange: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced'],
-  group: ['label', 'type', 'field', 'datefield', 'initval', 'blacklist', 'ratio', 'items', 'required', 'labelShow']
+  group: ['label', 'type', 'field', 'datefield', 'initval', 'blacklist', 'ratio', 'items', 'required', 'labelShow'],
+  range: ['label', 'type', 'field', 'initval', 'blacklist', 'maxValue', 'minValue', 'step', 'labelShow']
 }
 
 class MainSearch extends Component {
@@ -174,7 +175,7 @@
             form.options = matchReg.date
           } else if (type === 'datemonth') {
             form.options = matchReg.datemonth
-          } else if (type === 'dateweek' || type === 'daterange') {
+          } else if (type === 'dateweek' || type === 'daterange' || type === 'range') {
             form.options = matchReg.daterange
           }
         } else if (form.key === 'field' && (type === 'text' || type === 'select')) {
@@ -265,7 +266,7 @@
               form.options = matchReg.date
             } else if (value === 'datemonth') {
               form.options = matchReg.datemonth
-            } else if (value === 'dateweek' || value === 'daterange') {
+            } else if (value === 'dateweek' || value === 'daterange' || value === 'range') {
               form.options = matchReg.daterange
             }
             matchs = form.options
@@ -443,14 +444,17 @@
               </Tooltip> : item.label
             }>
               {getFieldDecorator(item.key, {
-                initialValue: item.initVal || 6,
+                initialValue: item.initVal,
                 rules: [
                   {
                     required: item.required,
                     message: this.props.dict['form.required.input'] + item.label + '!'
                   }
                 ]
-              })(<InputNumber min={item.min} max={item.max} precision={0} onPressEnter={this.handleSubmit}/>)}
+              })(item.max ?
+                  <InputNumber min={item.min} max={item.max} precision={0} onPressEnter={this.handleSubmit}/> : 
+                  <InputNumber onPressEnter={this.handleSubmit}/>
+                )}
             </Form.Item>
           </Col>
         )
@@ -652,6 +656,47 @@
             values.options = []
           }
 
+          if (values.type === 'range') {
+            let error = ''
+            if (values.maxValue <= values.minValue) {
+              error = '鏈�澶у�煎繀椤诲ぇ浜庢渶灏忓��'
+            } else if (values.step <= 0) {
+              error = '姝ラ暱蹇呴』澶т簬0'
+            } else {
+              let s = (values.maxValue - values.minValue) / values.step
+              if (s !== parseInt(s)) {
+                error = '姝ラ暱蹇呴』琚� (max - min) 鏁撮櫎'
+              }
+            }
+
+            if (!error && values.initval) {
+              let vals = values.initval.split(',')
+              if (vals.length !== 2) {
+                error = '鍒濆鍊艰缃敊璇紒'
+              } else if (isNaN(parseFloat(vals[0])) || isNaN(parseFloat(vals[1]))) {
+                error = '鍒濆鍊艰缃敊璇紒'
+              } else {
+                let start = parseFloat(vals[0])
+                let end = parseFloat(vals[1])
+                let s = (values.maxValue - start) / values.step
+                let e = (values.maxValue - end) / values.step
+                if (start > end || start < values.minValue || end > values.maxValue) {
+                  error = '鍒濆鍊艰缃敊璇紒'
+                } else if (s !== parseInt(s) || e !== parseInt(e)) {
+                  error = '鍒濆鍊艰缃敊璇紒'
+                }
+              }
+            }
+            if (error) {
+              notification.warning({
+                top: 92,
+                message: error,
+                duration: 5
+              })
+              return
+            }
+          }
+
           if (isvalid) {
             ['linkField', 'valueField', 'valueText', 'orderBy'].forEach(item => {
               if (values[item]) {
diff --git a/src/templates/zshare/editcomponent/index.jsx b/src/templates/zshare/editcomponent/index.jsx
index 9ed56dc..3501574 100644
--- a/src/templates/zshare/editcomponent/index.jsx
+++ b/src/templates/zshare/editcomponent/index.jsx
@@ -141,26 +141,10 @@
             config: _config
           })
         })
-      } else if (options.includes('search') && (res.copyType === 'search' || res.copyType === 'form')) {
+      } else if (options.includes('search') && res.copyType === 'search') {
         res.uuid = Utils.getuuid()
         _config.search = _config.search.filter(item => !item.origin)
         let keys = _config.search.map(item => item.field.toLowerCase())
-
-        // search锛� text select multiselect link date dateweek datemonth daterange group
-        // form锛� text number select multiselect link switch checkbox radio checkcard
-        //       fileupload date datemonth datetime textarea hint color funcvar
-        if (res.copyType === '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'
-          }
-        }
-        res.copyType = 'search'
 
         _config.search.push(res)
 
@@ -206,20 +190,10 @@
             config: _config
           })
         })
-      } else if (options.includes('form') && (res.copyType === 'form' || res.copyType === 'search')) {
+      } else if (options.includes('form') && res.copyType === 'form') {
         let fields = []
         let labels = []
         res.uuid = Utils.getuuid()
-
-        // search锛� text select multiselect link date dateweek datemonth daterange group
-        // form锛� text number select multiselect link switch checkbox radio checkcard
-        //       fileupload date datemonth datetime textarea hint color funcvar
-        if (res.copyType === 'search') {
-          if (res.type === 'dateweek' || res.type === 'daterange' || res.type === 'group') {
-            res.type = 'date'
-          }
-        }
-        res.copyType = 'form'
 
         _config.fields.forEach(item => {
           item.field && fields.push(item.field.toLowerCase())
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index 4c77e23..6ce34b8 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -288,6 +288,7 @@
  */
 export function getSearchForm (card, linkableFields) {
   let roleList = sessionStorage.getItem('sysRoles')
+  let appType = sessionStorage.getItem('appType')
   if (roleList) {
     try {
       roleList = JSON.parse(roleList)
@@ -300,10 +301,10 @@
 
   let typeOptions = []
 
-  if (sessionStorage.getItem('appType') === 'mob') {
+  if (appType === 'mob') {
     typeOptions = [{
-      value: 'text',
-      text: Formdict['model.form.text']
+      value: 'range',
+      text: '鏁板�硷紙鍖洪棿锛�'
     }, {
       value: 'checkcard',
       text: '閫夐」鍗�'
@@ -313,10 +314,10 @@
     }, {
       value: 'datemonth',
       text: Formdict['model.form.datemonth']
+    }, {
+      value: 'daterange',
+      text: Formdict['model.form.daterange']
     }]
-    if (!['text', 'checkcard', 'date', 'datemonth'].includes(card.type)) {
-      card.type = 'text'
-    }
   } else {
     typeOptions = [{
       value: 'text',
@@ -349,6 +350,18 @@
       value: 'group',
       text: Formdict['model.form.dategroup']
     }]
+  }
+
+  if (card.focus) {
+    if (['text', 'multiselect'].includes(card.type)) {
+      card.match = 'like'
+    } else if (['select', 'link', 'checkcard'].includes(card.type)) {
+      card.match = '='
+    } else if (card.type === 'date') {
+      card.match = '>='
+    } else if (['datemonth', 'dateweek', 'daterange', 'range'].includes(card.type)) {
+      card.match = 'between'
+    }
   }
 
   return [
@@ -389,7 +402,7 @@
       type: 'text',
       key: 'initval',
       label: Formdict['header.form.initval'],
-      tooltip: '绫诲瀷涓轰笅鎷夎彍鍗曟椂锛屽垵濮嬪�煎簲涓烘暟鎹殑Value鍊硷紙浣跨敤鏁版嵁婧愭椂锛屽簲涓恒�婂�悸峰瓧娈点�嬬殑鍊硷級',
+      tooltip: '绫诲瀷涓轰笅鎷夎彍鍗曟椂锛屽垵濮嬪�煎簲涓烘暟鎹殑Value鍊硷紙浣跨敤鏁版嵁婧愭椂锛屽簲涓恒�婂�悸峰瓧娈点�嬬殑鍊硷級;绫诲瀷涓烘暟鍊硷紙鍖洪棿锛夋椂锛屽垵濮嬪�间娇鐢ㄩ�楀彿鎷兼帴锛屼緥濡� 3,10',
       initVal: card.initval,
       required: false
     },
@@ -440,7 +453,7 @@
       min: 1,
       max: 24,
       precision: 0,
-      label: '鍗$墖瀹藉害',
+      label: '鍏冪礌瀹藉害',
       initVal: card.width || 4,
       tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       required: true
@@ -621,7 +634,8 @@
       max: 24,
       label: Formdict['header.form.ratio'],
       tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
-      initVal: card.ratio,
+      initVal: card.ratio || 6,
+      forbid: appType === 'mob',
       required: false
     },
     {
@@ -679,6 +693,31 @@
     //   }]
     // },
     {
+      type: 'number',
+      key: 'maxValue',
+      label: '鏈�澶у��',
+      initVal: card.maxValue,
+      forbid: appType !== 'mob',
+      required: true
+    },
+    {
+      type: 'number',
+      key: 'minValue',
+      label: '鏈�灏忓��',
+      initVal: card.minValue,
+      forbid: appType !== 'mob',
+      required: true
+    },
+    {
+      type: 'number',
+      key: 'step',
+      label: '姝ラ暱',
+      initVal: card.step,
+      tooltip: '姝ラ暱鍙栧�煎繀椤诲ぇ浜� 0锛屽苟涓斿彲琚� (max - min) 鏁撮櫎',
+      forbid: appType !== 'mob',
+      required: true
+    },
+    {
       type: 'radio',
       key: 'labelShow',
       label: '鏄剧ず鍚嶇О',
@@ -696,7 +735,7 @@
       key: 'advanced',
       label: '楂樼骇鎼滅储',
       initVal: card.advanced || 'false',
-      forbid: sessionStorage.getItem('appType') === 'mob',
+      forbid: appType === 'mob',
       options: [{
         value: 'true',
         text: Formdict['model.true']
@@ -711,7 +750,7 @@
       label: '杈撳叆鏍峰紡',
       initVal: card.inputType || 'input',
       required: false,
-      forbid: sessionStorage.getItem('appType') === null,
+      forbid: appType === null,
       options: [{
         value: 'input',
         text: '杈撳叆妗�'
@@ -2315,7 +2354,7 @@
       min: 1,
       max: 24,
       precision: 0,
-      label: '鍗$墖瀹藉害',
+      label: '鍏冪礌瀹藉害',
       initVal: card.width || 4,
       tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       required: true
@@ -2670,6 +2709,20 @@
       }]
     },
     {
+      type: 'radio',
+      key: 'arrange',
+      label: '鍏冪礌鎺掑垪',
+      initVal: card.arrange || 'adaptive',
+      forbid: appType !== 'mob',
+      options: [{
+        value: 'line',
+        text: '鏁磋'
+      }, {
+        value: 'adaptive',
+        text: '鑷�傚簲'
+      }]
+    },
+    {
       type: 'color',
       key: 'backgroundColor',
       label: '鑳屾櫙鑹�',
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index ff1a91c..a8bb337 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -19,8 +19,8 @@
   text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline'],
   number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline'],
   select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline'],
-  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline'],
-  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText', 'splitline'],
+  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'arrange'],
+  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText', 'splitline', 'arrange'],
   checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'borderColor', 'splitline'],
   multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra'],
   link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline'],

--
Gitblit v1.8.0