From 7ea1c5f53702951fc4df60e969fc67ef5d7af4dd Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 14 一月 2020 10:13:05 +0800
Subject: [PATCH] 2020-01-14

---
 src/tabviews/tableshare/mutilform/index.jsx       |   29 +
 src/templates/formtabconfig/editable/index.jsx    |  258 +++++++++++++
 src/templates/modalconfig/index.scss              |   31 +
 src/templates/tableshare/dragelement/index.jsx    |   21 -
 src/templates/formtabconfig/index.jsx             |  201 +++++++--
 src/tabviews/tableshare/mutilform/index.scss      |   14 
 src/templates/comtableconfig/index.jsx            |   14 
 src/templates/modalconfig/dragelement/index.scss  |    4 
 src/templates/formtabconfig/modalform/index.jsx   |  411 +++++++++++++++++++++
 src/templates/formtabconfig/dragelement/index.jsx |   15 
 src/templates/modalconfig/index.jsx               |   10 
 src/templates/formtabconfig/editable/index.scss   |   36 +
 src/templates/formtabconfig/modalform/index.scss  |   16 
 src/templates/formtabconfig/source.jsx            |   36 +
 src/templates/modalconfig/dragelement/index.jsx   |   11 
 src/locales/zh-CN/comtable.js                     |    3 
 src/templates/modalconfig/dragelement/card.jsx    |   19 
 src/locales/en-US/comtable.js                     |    3 
 src/templates/formtabconfig/index.scss            |    5 
 src/utils/option.js                               |    3 
 20 files changed, 1,018 insertions(+), 122 deletions(-)

diff --git a/src/locales/en-US/comtable.js b/src/locales/en-US/comtable.js
index 3357cac..ed31042 100644
--- a/src/locales/en-US/comtable.js
+++ b/src/locales/en-US/comtable.js
@@ -84,6 +84,9 @@
   'header.form.text': 'Text',
   'header.form.description': '鎻忚堪',
   'header.form.textarea': '澶氳鏂囨湰',
+  'header.form.fileupload': '鏂囦欢涓婁紶',
+  'header.form.funcvar': '鍑芥暟鍙橀噺',
+  'header.form.linkForm': '鍏宠仈琛ㄥ崟',
   'header.form.picture': '鍥剧墖',
   'header.form.number': '鏁板瓧',
   'header.form.colspan': '鍚堝苟鍒�',
diff --git a/src/locales/zh-CN/comtable.js b/src/locales/zh-CN/comtable.js
index 917d5c1..4d89eb6 100644
--- a/src/locales/zh-CN/comtable.js
+++ b/src/locales/zh-CN/comtable.js
@@ -84,6 +84,9 @@
   'header.form.text': '鏂囨湰',
   'header.form.description': '鎻忚堪',
   'header.form.textarea': '澶氳鏂囨湰',
+  'header.form.fileupload': '鏂囦欢涓婁紶',
+  'header.form.funcvar': '鍑芥暟鍙橀噺',
+  'header.form.linkForm': '鍏宠仈琛ㄥ崟',
   'header.form.picture': '鍥剧墖',
   'header.form.number': '鏁板瓧',
   'header.form.colspan': '鍚堝苟鍒�',
diff --git a/src/tabviews/tableshare/mutilform/index.jsx b/src/tabviews/tableshare/mutilform/index.jsx
index 83fe6a0..064cd74 100644
--- a/src/tabviews/tableshare/mutilform/index.jsx
+++ b/src/tabviews/tableshare/mutilform/index.jsx
@@ -8,6 +8,7 @@
 import './index.scss'
 
 const {MonthPicker} = DatePicker
+const { TextArea } = Input
 
 class MainSearch extends Component {
   static propTpyes = {
@@ -61,7 +62,7 @@
     let _inputfields = formlist.filter(item => item.type === 'text' || item.type === 'number') // 鐢ㄤ簬杩囨护涓嬫媺鑿滃崟鍏宠仈琛ㄥ崟
 
     formlist = formlist.map(item => {
-      if (item.type === 'select' || item.type === 'link') {
+      if (item.type === 'select' || item.type === 'link' || item.type === 'multiselect') {
         if (item.setAll === 'true') {
           item.options.unshift({
             key: Utils.getuuid(),
@@ -461,6 +462,32 @@
             </Form.Item>
           </Col>
         )
+      } else if (item.type === 'textarea') {
+        let _labelcol = cols !== 3 ? 8 / cols : 3
+        let _wrapcol = cols !== 3 ? 16 + (cols - 1) * 4 : 21
+        let _style = {}
+        if (cols === 2) {
+          _style.paddingLeft = '7px'
+        }
+        fields.push(
+          <Col span={24} key={index} className="textarea-row" style={{..._style}}>
+            <Form.Item label={item.label} labelCol={{xs: { span: 24 }, sm: { span: _labelcol }}} wrapperCol={ {xs: { span: 24 }, sm: { span: _wrapcol }} }>
+              {getFieldDecorator(item.field, {
+                initialValue: item.initval || '',
+                rules: [
+                  {
+                    required: item.required === 'true',
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  },
+                  {
+                    max: formRule.textarea.max,
+                    message: formRule.textarea.message
+                  }
+                ]
+              })(<TextArea autosize={{ minRows: 2, maxRows: 6 }} disabled={item.readonly === 'true'} />)}
+            </Form.Item>
+          </Col>
+        )
       }
     })
     
diff --git a/src/tabviews/tableshare/mutilform/index.scss b/src/tabviews/tableshare/mutilform/index.scss
index 2a79447..62fcc66 100644
--- a/src/tabviews/tableshare/mutilform/index.scss
+++ b/src/tabviews/tableshare/mutilform/index.scss
@@ -3,13 +3,23 @@
   padding: 0px 24px 20px;
   .ant-form-item {
     display: flex;
-    // margin-bottom: 10px;
   }
   .ant-form-item-control-wrapper {
     flex: 1;
   }
   .ant-form-item-label {
-    min-width: 100px;
+    overflow: hidden;
+    display: inline-block;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .textarea-row {
+    .ant-col-sm-3 {
+      width: 10.5%;
+    }
+    .ant-col-sm-21 {
+      width: 89.5%;
+    }
   }
   .ant-input-number {
     width: 100%;
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index 89d3e62..564910d 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -354,7 +354,7 @@
           type: 'text',
           key: 'label',
           label: this.state.dict['header.form.name'],
-          initVal: card.label,
+          initVal: card.label || '',
           required: true,
           readonly: false
         },
@@ -362,7 +362,7 @@
           type: 'text',
           key: 'field',
           label: this.state.dict['header.form.field'],
-          initVal: card.field,
+          initVal: card.field || '',
           tooltip: '瀛楁鍚嶅彲浠ヤ娇鐢ㄩ�楀彿鍒嗛殧锛岃繘琛屽瀛楁缁煎悎鎼滅储锛屾敞锛氱患鍚堟悳绱粎鍦ㄦ枃鏈被鍨嬫椂鏈夋晥',
           tooltipClass: 'middle',
           required: true,
@@ -612,7 +612,7 @@
           type: 'select',
           key: 'pageTemplate',
           label: this.state.dict['header.form.pageTemplate'],
-          initVal: card.pageTemplate,
+          initVal: card.pageTemplate || '',
           required: true,
           options: []
         },
@@ -641,7 +641,7 @@
           type: 'text',
           key: 'innerFunc',
           label: this.state.dict['header.form.innerFunc'],
-          initVal: card.innerFunc,
+          initVal: card.innerFunc || '',
           tooltip: <div>
             <p>鍐呴儴鎺ュ彛: 鍙嚜瀹氫箟鏁版嵁澶勭悊鍑芥暟锛屽嚱鏁板悕绉伴渶浠ableField}绛夊瓧绗﹀紑濮嬶紱鏈缃椂浼氳皟鐢ㄧ郴缁熷嚱鏁帮紝浣跨敤绯荤粺鍑芥暟闇�瀹屽杽鏁版嵁婧愬強鎿嶄綔绫诲瀷;</p>
             <p>澶栭儴鎺ュ彛: 鍙嚜瀹氫箟鏁版嵁澶勭悊鍑芥暟锛屾彁浜ゆ暟鎹粡杩囧唴閮ㄥ嚱鏁板鐞嗗悗锛屼紶鍏ュ閮ㄦ帴鍙o紝鏈缃椂锛屾暟鎹細鐩存帴浼犲叆澶栭儴鎺ュ彛銆�</p>
@@ -669,7 +669,7 @@
           type: 'text',
           key: 'outerFunc',
           label: this.state.dict['header.form.outerFunc'],
-          initVal: card.outerFunc,
+          initVal: card.outerFunc || '',
           required: false,
           readonly: false
         },
@@ -677,7 +677,7 @@
           type: 'text',
           key: 'interface',
           label: this.state.dict['header.form.interface'],
-          initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : card.interface,
+          initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || window.GLOB.subSystemApi) : (card.interface || ''),
           required: true,
           readonly: card.sysInterface === 'true'
         },
@@ -685,7 +685,7 @@
           type: 'text',
           key: 'callbackFunc',
           label: this.state.dict['header.form.callbackFunc'],
-          initVal: card.callbackFunc,
+          initVal: card.callbackFunc || '',
           required: false,
           readonly: false
         },
diff --git a/src/templates/formtabconfig/dragelement/index.jsx b/src/templates/formtabconfig/dragelement/index.jsx
index 530e296..83ca042 100644
--- a/src/templates/formtabconfig/dragelement/index.jsx
+++ b/src/templates/formtabconfig/dragelement/index.jsx
@@ -63,6 +63,14 @@
   const [, drop] = useDrop({
     accept: ItemTypes[type],
     drop(item) {
+      if (item.hasOwnProperty('originalIndex') && groupId) {
+        const { card } = findCard(item.id)
+
+        if (!card) {
+          handleList(type, cards, null, groupId, item.id)
+        }
+      }
+
       if (item.hasOwnProperty('originalIndex')) {
         return
       }
@@ -134,7 +142,7 @@
 
       const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
       setCards(_cards)
-      handleList(type, _cards, newcard)
+      handleList(type, _cards, newcard, groupId)
       target = null
     }
   })
@@ -144,7 +152,7 @@
       {type === 'action' && cards.map(card => (
         <Card
           key={card.uuid}
-          id={`${card.uuid}`}
+          id={card.uuid}
           type={type}
           card={card}
           moveCard={moveCard}
@@ -159,7 +167,8 @@
       {type === 'search' && cards.map(card => (
         <Col key={card.uuid} span={24 / setting.cols}>
           <Card
-            id={`${card.uuid}`}
+            id={card.uuid}
+            key={card.uuid}
             type={type}
             card={card}
             moveCard={moveCard}
diff --git a/src/templates/formtabconfig/editable/index.jsx b/src/templates/formtabconfig/editable/index.jsx
new file mode 100644
index 0000000..4f10603
--- /dev/null
+++ b/src/templates/formtabconfig/editable/index.jsx
@@ -0,0 +1,258 @@
+import React, {Component} from 'react'
+import { Table, Input, Button, Popconfirm, Form, Icon } from 'antd'
+import Utils from '@/utils/utils.js'
+import './index.scss'
+
+const EditableContext = React.createContext()
+
+const EditableRow = ({ form, index, ...props }) => (
+  <EditableContext.Provider value={form}>
+    <tr {...props} />
+  </EditableContext.Provider>
+)
+
+const EditableFormRow = Form.create()(EditableRow)
+
+class EditableCell extends Component {
+  state = {
+    editing: false
+  }
+
+  toggleEdit = () => {
+    const editing = !this.state.editing
+    this.setState({ editing }, () => {
+      if (editing) {
+        this.input.focus()
+      }
+    })
+  }
+
+  save = e => {
+    const { record, handleSave } = this.props
+    this.form.validateFields((error, values) => {
+      handleSave({ ...record, ...values })
+      if (error && error[e.currentTarget.id]) {
+        return
+      }
+      this.toggleEdit()
+      // handleSave({ ...record, ...values })
+    })
+  }
+
+  renderCell = form => {
+    this.form = form
+    const { children, dataIndex, record } = this.props
+    const { editing } = this.state
+    return editing ? (
+      <Form.Item style={{ margin: 0 }}>
+        {form.getFieldDecorator(dataIndex, {
+          rules: [
+            {
+              required: true,
+              message: 'NOT NULL.',
+            },
+          ],
+          initialValue: record[dataIndex]
+        })(<Input ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)}
+      </Form.Item>
+    ) : (
+      <div
+        className="editable-cell-value-wrap"
+        onClick={this.toggleEdit}
+      >
+        {children}
+      </div>
+    )
+  }
+
+  render() {
+    const {
+      editable,
+      dataIndex,
+      title,
+      record,
+      index,
+      handleSave,
+      children,
+      ...restProps
+    } = this.props
+    return (
+      <td {...restProps}>
+        {editable ? (
+          <EditableContext.Consumer style={{padding: 0}}>{this.renderCell}</EditableContext.Consumer>
+        ) : (
+          children
+        )}
+      </td>
+    )
+  }
+}
+
+class EditTable extends Component {
+  constructor(props) {
+    super(props)
+    let columns = [
+      {
+        title: 'Value',
+        dataIndex: 'Value',
+        width: props.type === 'link' ? '27%' : '40%',
+        editable: true
+      },
+      {
+        title: 'Text',
+        dataIndex: 'Text',
+        width: props.type === 'link' ? '27%' : '40%',
+        editable: true
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          this.state.dataSource.length >= 1 ? (
+            <Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
+              <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
+            </Popconfirm>
+          ) : null,
+      }
+    ]
+
+    if (props.type === 'link') {
+      columns.unshift({
+        title: 'ParentID',
+        dataIndex: 'ParentID',
+        width: '27%',
+        editable: true
+      })
+    }
+
+    this.state = {
+      columns: columns,
+      dataSource: props.data,
+      count: props.data.length,
+      type: props.type
+    }
+  }
+
+  handleDelete = key => {
+    const dataSource = [...this.state.dataSource]
+    this.setState({ dataSource: dataSource.filter(item => item.key !== key) })
+  }
+
+  handleAdd = () => {
+    const { type, count, dataSource } = this.state
+    const newData = {
+      key: Utils.getuuid(),
+      Value: `${count}`,
+      Text: `${count}`
+    }
+    if (type === 'link') {
+      newData.ParentID = `${count}`
+    }
+    this.setState({
+      dataSource: [...dataSource, newData],
+      count: count + 1
+    })
+  }
+
+  handleSave = row => {
+    const newData = [...this.state.dataSource]
+    const index = newData.findIndex(item => row.key === item.key)
+    const item = newData[index]
+    newData.splice(index, 1, {
+      ...item,
+      ...row
+    })
+    this.setState({ dataSource: newData })
+  }
+
+  resetColumn = (type) => {
+    let columns = [
+      {
+        title: 'Value',
+        dataIndex: 'Value',
+        width: type === 'link' ? '27%' : '40%',
+        editable: true
+      },
+      {
+        title: 'Text',
+        dataIndex: 'Text',
+        width: type === 'link' ? '27%' : '40%',
+        editable: true
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          this.state.dataSource.length >= 1 ? (
+            <Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
+              <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
+            </Popconfirm>
+          ) : null,
+      }
+    ]
+
+    if (type === 'link') {
+      columns.unshift({
+        title: 'ParentID',
+        dataIndex: 'ParentID',
+        width: '27%',
+        editable: true
+      })
+    }
+
+    this.setState({
+      columns: columns,
+      type: type
+    })
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (this.props.type !== nextProps.type) {
+      this.resetColumn(nextProps.type)
+    }
+  }
+
+  render() {
+    const { dataSource } = this.state
+    const components = {
+      body: {
+        row: EditableFormRow,
+        cell: EditableCell
+      }
+    }
+    const columns = this.state.columns.map(col => {
+      if (!col.editable) {
+        return col
+      }
+      return {
+        ...col,
+        onCell: record => ({
+          record,
+          editable: col.editable,
+          dataIndex: col.dataIndex,
+          title: col.title,
+          handleSave: this.handleSave,
+        })
+      }
+    })
+    return (
+      <div className="common-modal-edit-table">
+        <Button onClick={this.handleAdd} type="primary" className="add-row">
+          娣诲姞
+        </Button>
+        <Table
+          components={components}
+          rowClassName={() => 'editable-row'}
+          bordered
+          dataSource={dataSource}
+          columns={columns}
+          pagination={false}
+        />
+      </div>
+    )
+  }
+}
+
+export default EditTable
\ No newline at end of file
diff --git a/src/templates/formtabconfig/editable/index.scss b/src/templates/formtabconfig/editable/index.scss
new file mode 100644
index 0000000..f8f0942
--- /dev/null
+++ b/src/templates/formtabconfig/editable/index.scss
@@ -0,0 +1,36 @@
+.common-modal-edit-table {
+  .add-row {
+    position: absolute;
+    z-index: 1;
+    right: 12px;
+    top: -40px;
+  }
+  .ant-table-thead > tr > th {
+    padding: 10px 16px;
+  }
+  .ant-table-tbody > tr > td {
+    padding: 0px 16px;
+  }
+  .editable-cell-value-wrap {
+    cursor: pointer;
+    height: 40px;
+    width: 100px;
+    display: table-cell;
+    vertical-align: middle;
+    word-wrap: break-word;
+    word-break: break-word;
+    .ant-input {
+      height: 30px;
+      padding: 0 11px;
+    }
+  }
+  .ant-form-item-control-wrapper {
+    width: 100%;
+  }
+  .ant-table-placeholder {
+    padding: 5px 16px;
+    .ant-empty-normal {
+      margin: 0;
+    }
+  }
+}
diff --git a/src/templates/formtabconfig/index.jsx b/src/templates/formtabconfig/index.jsx
index c8e43f2..e8a15df 100644
--- a/src/templates/formtabconfig/index.jsx
+++ b/src/templates/formtabconfig/index.jsx
@@ -11,7 +11,7 @@
 import TabForm from './tabform'
 import TabDragElement from './tabdragelement'
 import Api from '@/api'
-import SearchForm from '@/templates/tableshare/searchform'
+import SearchForm from './modalform'
 import DragElement from './dragelement'
 import EditCard from '@/templates/tableshare/editcard'
 import VerifyCard from '@/templates/tableshare/verifycard'
@@ -52,7 +52,6 @@
     card: null,              // 缂栬緫鍏冪礌
     searchloading: false,    // 鎼滅储鏉′欢鍔犺浇涓�
     actionloading: false,    // 鎸夐挳鍔犺浇涓�
-    columnsloading: false,   // 鏄剧ず鍒楀姞杞戒腑
     tabloading: false,       // 鏍囩椤靛姞杞戒腑
     menuloading: false,      // 鑿滃崟淇濆瓨涓�
     menucloseloading: false, // 鑿滃崟鍏抽棴鏃讹紝閫夋嫨淇濆瓨
@@ -76,9 +75,6 @@
   UNSAFE_componentWillMount () {
     const { menu, editAction, config } = this.props
 
-    console.log(menu)
-    console.log(editAction)
-    console.log(config)
     let _config = ''
 
     if (!config) {
@@ -240,8 +236,8 @@
     }
   }
 
-  handleList = (type, list, card, groupId) => {
-    const { config } = this.state
+  handleList = (type, list, card, groupId, elementId) => {
+    let config = JSON.parse(JSON.stringify(this.state.config))
 
     if (type === 'tabs') { // 鏍囩椤佃皟鏁撮『搴忔垨娣诲姞鍏冪礌
       if (list.length > config[card.groupId].length) {
@@ -278,14 +274,77 @@
       } else {
         this.setState({config: {...config, action: list}})
       }
+    } else if (type === 'search') {
+      let _group = config.groups.filter(group => group.uuid === groupId)[0]
+      let isChange = list.length > _group.length
+      let isAdd = !elementId && list.length > _group.length
+
+      if (isAdd) {
+        _group.sublist = list.filter(item => !item.origin)
+        this.handleSearch(card)
+      } else if (elementId) {
+        // 淇敼宸叉湁鍏冪礌鐨勫垎缁�
+        let element = null
+        config.groups.forEach(item => {
+          item.sublist = item.sublist.filter(cell => {
+            if (cell.uuid !== elementId) {
+              return true
+            } else {
+              element = cell
+              return false
+            }
+          })
+        })
+        _group.sublist.push(element)
+      } else {
+        _group.sublist = list
+      }
+
+      config.groups = config.groups.map(item => {
+        if (item.uuid === _group.uuid) {
+          return _group
+        } else {
+          return item
+        }
+      })
+
+      if (isChange) {
+        this.setState({
+          searchloading: true,
+          config: config
+        }, () => {
+          // 鍒锋柊瀵瑰簲鐨勯厤缃俊鎭�
+          this.setState({
+            searchloading: false
+          })
+        })
+      } else {
+        this.setState({
+          config: config
+        })
+      }
     }
   }
 
   handleSearch = (card) => {
+    const { config } = this.state
+    let _inputfields = []
+
+    // 璁剧疆涓嬫媺鑿滃崟鍙叧鑱斿瓧娈�
+    config.groups.forEach(group => {
+      let sublist = group.sublist.filter(item => item.type === 'text' || item.type === 'number')
+      _inputfields = [..._inputfields, ...sublist]
+    })
+    
+    if (card.linkSubField && card.linkSubField.length > 0) {
+      let fields = _inputfields.map(item => item.field)
+      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
+    }
+
     this.setState({
       visible: true,
       formtemp: 'search',
-      modalTitle: '缂栬緫-鎼滅储鏉′欢',
+      modalTitle: '缂栬緫-琛ㄥ崟',
       card: card,
       formlist: [
         {
@@ -301,8 +360,6 @@
           key: 'field',
           label: this.state.dict['header.form.field'],
           initVal: card.field,
-          tooltip: '瀛楁鍚嶅彲浠ヤ娇鐢ㄩ�楀彿鍒嗛殧锛岃繘琛屽瀛楁缁煎悎鎼滅储锛屾敞锛氱患鍚堟悳绱粎鍦ㄦ枃鏈被鍨嬫椂鏈夋晥',
-          tooltipClass: 'middle',
           required: true,
           readonly: false
         },
@@ -316,6 +373,9 @@
             value: 'text',
             text: this.state.dict['header.form.text']
           }, {
+            value: 'number',
+            text: this.state.dict['header.form.number']
+          }, {
             value: 'select',
             text: this.state.dict['header.form.select']
           }, {
@@ -325,17 +385,20 @@
             value: 'link',
             text: this.state.dict['header.form.link']
           }, {
+            value: 'fileupload',
+            text: this.state.dict['header.form.fileupload']
+          }, {
             value: 'date',
             text: this.state.dict['header.form.dateday']
-          }, {
-            value: 'dateweek',
-            text: this.state.dict['header.form.dateweek']
           }, {
             value: 'datemonth',
             text: this.state.dict['header.form.datemonth']
           }, {
-            value: 'daterange',
-            text: this.state.dict['header.form.daterange']
+            value: 'datetime',
+            text: this.state.dict['header.form.datetime']
+          }, {
+            value: 'textarea',
+            text: this.state.dict['header.form.textarea']
           }]
         },
         {
@@ -434,41 +497,58 @@
           }]
         },
         {
-          type: 'select',
-          key: 'match',
-          label: this.state.dict['header.form.match'],
-          initVal: card.match || 'like',
-          required: true,
+          type: 'number',
+          key: 'decimal',
+          label: this.state.dict['header.form.decimal'],
+          initVal: card.decimal || 0,
+          required: false
+        },
+        {
+          type: 'number',
+          key: 'min',
+          label: '鏈�灏忓��',
+          initVal: card.min || '',
+          required: false
+        },
+        {
+          type: 'number',
+          key: 'max',
+          label: '鏈�澶у��',
+          initVal: card.max || '',
+          required: false
+        },
+        {
+          type: 'radio',
+          key: 'readonly',
+          label: this.state.dict['header.form.readonly'],
+          initVal: card.readonly || 'false',
           options: [{
-            value: 'like',
-            text: 'like'
+            value: 'true',
+            text: this.state.dict['header.form.true']
           }, {
-            value: 'equal',
-            text: 'equal'
-          }, {
-            value: 'greater',
-            text: '>'
-          }, {
-            value: 'less',
-            text: '<'
-          }, {
-            value: 'greaterequal',
-            text: '>='
+            value: 'false',
+            text: this.state.dict['header.form.false']
           }]
         },
         {
-          type: 'select',
-          key: 'display',
-          label: this.state.dict['header.form.display'],
-          initVal: card.display || 'dropdown',
-          required: true,
+          type: 'radio',
+          key: 'required',
+          label: this.state.dict['header.form.field.required'],
+          initVal: card.required || 'false',
           options: [{
-            value: 'dropdown',
-            text: this.state.dict['header.form.dropdown']
+            value: 'true',
+            text: this.state.dict['header.form.true']
           }, {
-            value: 'button',
-            text: this.state.dict['header.form.button']
+            value: 'false',
+            text: this.state.dict['header.form.false']
           }]
+        },
+        {
+          type: 'multiselect',
+          key: 'linkSubField',
+          label: this.state.dict['header.form.linkForm'],
+          initVal: card.linkSubField || [],
+          options: _inputfields
         }
       ]
     })
@@ -809,8 +889,9 @@
         })
       }
 
-      if (res.type !== 'tabs') {
-        _config[res.type] = _config[res.type].map(item => {
+      
+      if (res.type === 'action') {
+        _config.action = _config.action.map(item => {
           if (item.uuid === res.values.uuid) {
             isupdate = true
             return res.values
@@ -818,11 +899,25 @@
             return item
           }
         })
-        _config[res.type] = _config[res.type].filter(item => !item.origin)
+        _config.action = _config.action.filter(item => !item.origin)
   
         if (!isupdate) { // 鎿嶄綔涓嶆槸淇敼锛屾坊鍔犲厓绱犺嚦鍒楄〃
-          _config[res.type].push(res.values)
+          _config.action.push(res.values)
         }
+      } else if (res.type === 'search') {
+        _config.groups = _config.groups.map(item => {
+          item.sublist = item.sublist.map(cell => {
+            if (cell.uuid === res.values.uuid) {
+              return res.values
+            } else {
+              return cell
+            }
+          })
+          if (item.isDefault) {
+            item.sublist = item.sublist.filter(cell => !cell.origin)
+          }
+          return item
+        })
       } else { // 鏍囩椤电殑娣诲姞涓庝慨鏀�
         _config[res.values.groupId] = _config[res.values.groupId].map(item => {
           if (item.uuid === res.values.uuid) {
@@ -843,14 +938,12 @@
         config: _config,
         searchloading: true,
         actionloading: true,
-        columnsloading: true,
         tabloading: true,
         visible: false
       }, () => {
         this.setState({
           searchloading: false,
           actionloading: false,
-          columnsloading: false,
           tabloading: false
         })
       })
@@ -1564,13 +1657,11 @@
               ParentID: res.parentId
             },
             searchloading: true,
-            actionloading: true,
-            columnsloading: true
+            actionloading: true
           }, () => {
             this.setState({
               searchloading: false,
-              actionloading: false,
-              columnsloading: false
+              actionloading: false
             })
           })
 
@@ -2004,11 +2095,9 @@
       this.setState({
         config: {...config, setting: res},
         settingVisible: false,
-        columnsloading: true,
         tabloading: true
       }, () => {
         this.setState({
-          columnsloading: false,
           tabloading: false
         })
       })
@@ -2269,13 +2358,13 @@
                 />}
               </Panel>
               {/* 鎼滅储鏉′欢娣诲姞 */}
-              <Panel header={this.state.dict['header.menu.search']} key="1">
+              <Panel header={this.state.dict['header.menu.form']} key="1">
                 <div className="search-element">
                   {Source.searchItems.map((item, index) => {
                     return (<SourceElement key={index} content={item}/>)
                   })}
                 </div>
-                <Button type="primary" block onClick={() => this.queryField('search')}>{this.state.dict['header.menu.search.add']}</Button>
+                <Button type="primary" block onClick={() => this.queryField('search')}>{this.state.dict['header.menu.form.add']}</Button>
               </Panel>
               {/* 鎸夐挳娣诲姞 */}
               <Panel header={this.state.dict['header.menu.action']} key="2">
diff --git a/src/templates/formtabconfig/index.scss b/src/templates/formtabconfig/index.scss
index f43082a..cafce11 100644
--- a/src/templates/formtabconfig/index.scss
+++ b/src/templates/formtabconfig/index.scss
@@ -173,13 +173,16 @@
           border-radius: 0;
           background: #1890ff;
           color: #ffffff;
+          padding-left: 30px;
+          padding-right: 20px;
           .anticon {
             font-size: 16px;
           }
           .ant-collapse-extra {
             .anticon-edit {
               position: absolute;
-              right: 15px;
+              left: 5px;
+              top: 2px;
             }
           }
         }
diff --git a/src/templates/formtabconfig/modalform/index.jsx b/src/templates/formtabconfig/modalform/index.jsx
new file mode 100644
index 0000000..6a8c3b3
--- /dev/null
+++ b/src/templates/formtabconfig/modalform/index.jsx
@@ -0,0 +1,411 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input, Select, Icon, Radio, notification, InputNumber } from 'antd'
+import { formRule } from '@/utils/option.js'
+import { dateOptions } from '@/utils/option.js'
+import EditTable from '../editable'
+import './index.scss'
+
+const { TextArea } = Input
+
+class MainSearch extends Component {
+  static propTpyes = {
+    dict: PropTypes.object, // 瀛楀吀椤�
+    formlist: PropTypes.any,
+    card: PropTypes.object
+  }
+
+  state = {
+    openType: null,
+    resourceType: null,
+    formlist: null
+  }
+
+  UNSAFE_componentWillMount () {
+    let formlist = JSON.parse(JSON.stringify(this.props.formlist))
+
+    let type = formlist.filter(cell => cell.key === 'type')[0].initVal
+    let resourceType = formlist.filter(cell => cell.key === 'resourceType')[0].initVal
+    let _options = ['label', 'field', 'initval', 'type', 'readonly', 'required'] // 榛樿鏄剧ず椤�
+
+    if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') { // 閫夋嫨绫诲瀷銆佽嚜瀹氫箟璧勬簮
+      _options = [..._options, 'resourceType', 'options']
+    } else if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '1') { // 閫夋嫨绫诲瀷銆佹暟鎹簮
+      _options = [..._options, 'resourceType', 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType']
+    } else if (type === 'number') {
+      _options = [..._options, 'decimal', 'min', 'max']
+    } else if (type === 'fileupload') {
+      _options = ['label', 'field', 'type', 'readonly', 'required']
+    }
+
+    if (type === 'select') {
+      _options = [..._options, 'setAll', 'linkSubField']
+    } else if (type === 'link') {          // 鍏宠仈绫诲瀷銆佸鍔犲叧鑱斿瓧娈�
+      _options = [..._options, 'setAll', 'linkField']
+    } else if (type === 'funcvar') {       // 璁剧疆涓哄嚱鏁板彉閲忔椂锛屼笉闇�瑕佸叾浠栦俊鎭�
+      _options = ['label', 'field', 'type']
+    }
+    
+    this.setState({
+      openType: type,
+      resourceType: resourceType,
+      formlist: formlist.map(form => {
+        if (dateOptions.hasOwnProperty(type) && form.key === 'initval') {
+          form.options = dateOptions[type]
+          form.type = 'select'
+        } else if (type === 'number' && form.key === 'initval') {
+          form.type = 'number'
+          form.initVal = 0
+        }
+        form.hidden = !_options.includes(form.key)
+        return form
+      })
+    })
+  }
+
+  componentDidMount () {
+    const { card } = this.props
+
+    if (card.focus) {
+      try {
+        let _form = document.getElementById('label')
+        _form.select()
+      } catch {
+        console.warn('琛ㄥ崟focus澶辫触锛�')
+      }
+    }
+  }
+
+  openTypeChange = (key, value) => {
+    if (key === 'type') {
+      let _options = ['label', 'field', 'initval', 'type', 'readonly', 'required']
+
+      if ((value === 'multiselect' || value === 'select' || value === 'link') && this.state.resourceType === '0') { // 閫夋嫨绫诲瀷銆佽嚜瀹氫箟璧勬簮
+        _options = [..._options, 'resourceType', 'options']
+      } else if ((value === 'multiselect' || value === 'select' || value === 'link') && this.state.resourceType === '1') { // 閫夋嫨绫诲瀷銆佹暟鎹簮
+        _options = [..._options, 'resourceType', 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType']
+      } else if (value === 'number') {
+        _options = [..._options, 'decimal', 'min', 'max']
+      } else if (value === 'fileupload') {
+        _options = ['label', 'field', 'type', 'readonly', 'required']
+      }
+
+      if (value === 'select') {
+        _options = [..._options, 'setAll', 'linkSubField']
+      } else if (value === 'link') {
+        _options = [..._options, 'setAll', 'linkField']
+      } else if (value === 'funcvar') {
+        _options = ['label', 'field', 'type']
+      }
+      
+      this.setState({
+        openType: value,
+        formlist: this.state.formlist.map(form => {
+          form.hidden = !_options.includes(form.key)
+          if (form.key === 'initval') {
+            if (dateOptions.hasOwnProperty(value)) {
+              form.options = dateOptions[value]
+              form.type = 'select'
+              form.initVal = ''
+            } else if (value === 'number') {
+              form.type = 'number'
+              form.initVal = 0
+            } else {
+              form.type = 'text'
+              form.initVal = ''
+            }
+            form.hidden = true
+          }
+          return form
+        })
+      }, () => {
+        this.setState({
+          formlist: this.state.formlist.map(form => {
+            if (form.key === 'initval' && value !== 'fileupload' && value !== 'funcvar') {
+              form.hidden = false
+            }
+            return form
+          })
+        })
+      })
+    }
+  }
+
+  onChange = (e, key) => {
+    const { openType } = this.state
+    let value = e.target.value
+    if (key === 'resourceType') {
+      let _options = ['label', 'field', 'initval', 'type', 'resourceType', 'readonly', 'required']
+      if (value === '0') {
+        _options = [..._options, 'options']
+      } else if (value === '1') {
+        _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType']
+      }
+
+      if (openType === 'select') {
+        _options = [..._options, 'setAll', 'linkSubField']
+      } else if (openType === 'link') {
+        _options = [..._options, 'setAll', 'linkField']
+      }
+      
+      this.setState({
+        resourceType: value,
+        formlist: this.state.formlist.map(form => {
+          form.hidden = !_options.includes(form.key)
+          return form
+        })
+      })
+    }
+  }
+
+  getFields() {
+    const { getFieldDecorator } = this.props.form
+    const fields = []
+
+    this.state.formlist.forEach((item, index) => {
+      if (item.hidden) return
+
+      if (item.type === 'text') { // 鏂囨湰鎼滅储
+        let rules = []
+        if (item.key === 'field') {
+          rules = [{
+            pattern: formRule.field.pattern,
+            message: formRule.field.message
+          }, {
+            max: formRule.field.max,
+            message: formRule.field.maxMessage
+          }]
+        } else {
+          rules = [
+            {
+              max: formRule.input.max,
+              message: formRule.input.message
+            }
+          ]
+        }
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || '',
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  },
+                  ...rules
+                ]
+              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'number') {
+        if (item.key === 'decimal') {
+          fields.push(
+            <Col span={12} key={index}>
+              <Form.Item label={item.label}>
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal || 0,
+                  rules: [
+                    {
+                      required: !!item.required,
+                      message: this.props.dict['form.required.input'] + item.label + '!'
+                    }
+                  ]
+                })(<InputNumber min={0} max={18} precision={0} />)}
+              </Form.Item>
+            </Col>
+          )
+        } else {
+          fields.push(
+            <Col span={12} key={index}>
+              <Form.Item label={item.label}>
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal,
+                  rules: [
+                    {
+                      required: !!item.required,
+                      message: this.props.dict['form.required.input'] + item.label + '!'
+                    }
+                  ]
+                })(<InputNumber />)}
+              </Form.Item>
+            </Col>
+          )
+        }
+      } else if (item.type === 'select') { // 涓嬫媺鎼滅储
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || '',
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Select
+                  showSearch
+                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                  onChange={(value) => {this.openTypeChange(item.key, value)}}
+                  getPopupContainer={() => document.getElementById('modal-fields-form-box')}
+                >
+                  {item.options.map(option =>
+                    <Select.Option id={option.value} title={option.text} key={option.value} value={option.value}>
+                      {item.key === 'icon' && <Icon type={option.text} />} {option.text}
+                    </Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'multiselect') { // 澶氶��
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal
+              })(
+                <Select
+                  showSearch
+                  mode="multiple"
+                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                >
+                  {item.options.map(option =>
+                    <Select.Option id={option.uuid} key={option.uuid} value={option.field}>{option.label}</Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'radio') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Radio.Group onChange={(e) => {this.onChange(e, item.key)}}>
+                  {
+                    item.options.map(option => {
+                      return (
+                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
+                      )
+                    })
+                  }
+                </Radio.Group>,
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'textarea') {
+        fields.push(
+          <Col span={20} offset={4} key={index}>
+            <Form.Item className="text-area">
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<TextArea rows={4} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'options') {
+        fields.push(
+          <Col span={20} offset={4} key={index}>
+            <EditTable data={item.initVal} type={this.state.openType} ref="editTable"/>
+          </Col>
+        )
+      }
+    })
+
+    return fields
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          let isvalid = true
+          values.uuid = this.props.card.uuid
+          // 涓嬫媺鑿滃崟鎴栧叧鑱旇彍鍗�
+          if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '0') {
+            values.options = this.refs.editTable.state.dataSource
+            values.dataSource = ''
+            let emptys = []
+            if (values.type === 'multiselect' || values.type === 'select') {
+              emptys = values.options.filter(op => !(op.Value && op.Text))
+            } else {
+              emptys = values.options.filter(op => !(op.Value && op.Text && op.ParentID))
+            }
+            if (emptys.length > 0) {
+              isvalid = false
+              notification.warning({
+                top: 92,
+                message: this.props.dict['header.form.selectItem.error'],
+                duration: 10
+              })
+            }
+          } else if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '1') {
+            values.options = []
+          } else if (values.type === 'funcvar') { // 鍑芥暟鍙橀噺涓哄彧璇诲厓绱�
+            values.readonly = 'true'
+          } else if (values.type === 'number' && (values.min || values.min === 0) && (values.max || values.max === 0)) { // 鏁板�煎瀷楠岃瘉鏈�灏忔渶澶у��
+            if (values.min > values.max) {
+              isvalid = false
+              notification.warning({
+                top: 92,
+                message: '鏈�灏忓�间笉鍙ぇ浜庢渶澶у�硷紒',
+                duration: 10
+              })
+            }
+          }
+
+          if (isvalid) {
+            resolve({
+              type: 'search',
+              values
+            })
+          }
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  render() {
+    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-fields-form" id="modal-fields-form-box">
+        <Row gutter={24}>{this.getFields()}</Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(MainSearch)
\ No newline at end of file
diff --git a/src/templates/formtabconfig/modalform/index.scss b/src/templates/formtabconfig/modalform/index.scss
new file mode 100644
index 0000000..0cdacad
--- /dev/null
+++ b/src/templates/formtabconfig/modalform/index.scss
@@ -0,0 +1,16 @@
+.ant-advanced-search-form.modal-fields-form {
+  min-height: 180px;
+  .ant-col-offset-4 {
+    padding-left: 6px!important;
+    padding-bottom: 20px;
+  }
+  .ant-form-item.text-area {
+    margin-bottom: 0px;
+    .ant-form-item-control-wrapper {
+      width: 100%;
+    }
+  }
+  .ant-input-number {
+    width: 100%;
+  }
+}
\ No newline at end of file
diff --git a/src/templates/formtabconfig/source.jsx b/src/templates/formtabconfig/source.jsx
index 267165c..6c209eb 100644
--- a/src/templates/formtabconfig/source.jsx
+++ b/src/templates/formtabconfig/source.jsx
@@ -214,38 +214,50 @@
   searchItems = [
     {
       type: 'search',
-      label: '鏂囨湰妗�',
+      label: '鏂囨湰',
       subType: 'text',
       url: ''
     },
     {
       type: 'search',
-      label: '涓嬫媺妗�',
+      label: '鏁板瓧',
+      subType: 'number',
+      url: ''
+    },
+    {
+      type: 'search',
+      label: '涓嬫媺閫夋嫨',
       subType: 'select',
       url: ''
     },
     {
       type: 'search',
-      label: '鏃堕棿妗嗭紙澶╋級',
+      label: '鏂囦欢涓婁紶',
+      subType: 'fileupload',
+      url: ''
+    },
+    {
+      type: 'search',
+      label: '鏃堕棿锛堝ぉ锛�',
       subType: 'date',
       url: ''
     },
     {
       type: 'search',
-      label: '鏃堕棿妗嗭紙鍛級',
-      subType: 'dateweek',
-      url: ''
-    },
-    {
-      type: 'search',
-      label: '鏃堕棿妗嗭紙鏈堬級',
+      label: '鏃堕棿锛堟湀锛�',
       subType: 'datemonth',
       url: ''
     },
     {
       type: 'search',
-      label: '鏃堕棿妗嗭紙鍖洪棿锛�',
-      subType: 'daterange',
+      label: '鏃堕棿锛堢锛�',
+      subType: 'datetime',
+      url: ''
+    },
+    {
+      type: 'search',
+      label: '澶氳鏂囨湰',
+      subType: 'textarea',
       url: ''
     }
   ]
diff --git a/src/templates/modalconfig/dragelement/card.jsx b/src/templates/modalconfig/dragelement/card.jsx
index ea5c8e2..d1fda91 100644
--- a/src/templates/modalconfig/dragelement/card.jsx
+++ b/src/templates/modalconfig/dragelement/card.jsx
@@ -8,7 +8,7 @@
 const { MonthPicker } = DatePicker
 const { TextArea } = Input
 
-const Card = ({ id, card, moveCard, findCard, editCard, closeCard, hasDrop }) => {
+const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, hasDrop }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: ItemTypes.form, id, originalIndex },
@@ -55,15 +55,26 @@
       selectval = '鍏ㄩ儴'
     }
   }
+  let labelCol = 'ant-col-sm-8'
+  let wrapCol = 'ant-col-sm-16'
+  if (card.type === 'textarea') {
+    if (cols === '2') {
+      labelCol = 'ant-col-sm-4'
+      wrapCol = 'ant-col-sm-20'
+    } else if (cols === '3') {
+      labelCol = 'ant-col-cuslabel'
+      wrapCol = 'ant-col-cuswrap'
+    }
+  }
 
   return (
     <div className="page-card" style={{ opacity: opacity}}>
       <div ref={node => drag(drop(node))}>
         {<div className="ant-row ant-form-item">
-          <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
+          <div className={'ant-col ant-form-item-label ant-col-xs-24 ' + labelCol}>
             <label title={card.label}>{card.label}</label>
           </div>
-          <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16">
+          <div className={'ant-col ant-form-item-control-wrapper ant-col-xs-24 ' + wrapCol}>
             {card.type === 'text' &&
               <Input style={{marginTop: '4px'}} defaultValue={card.initval} />
             }
@@ -83,7 +94,7 @@
               <DatePicker showTime defaultValue={card.initval ? moment().subtract(card.initval, 'days') : null} />
             }
             {card.type === 'textarea' &&
-              <TextArea autoSize={{ minRows: 2, maxRows: 6 }} />
+              <TextArea autosize={{ minRows: 2, maxRows: 6 }} />
             }
             {card.type === 'fileupload' &&
               <Button>
diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx
index 677b61d..ab122e1 100644
--- a/src/templates/modalconfig/dragelement/index.jsx
+++ b/src/templates/modalconfig/dragelement/index.jsx
@@ -90,12 +90,8 @@
 
       const { index: overIndex } = findCard(`${targetId}`)
       let targetIndex = overIndex
-      // if (!target) {
+
       targetIndex++
-      // }
-      // if (targetIndex < 0) {
-      //   targetIndex = 0
-      // }
 
       const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
       setCards(_cards)
@@ -115,9 +111,10 @@
   return (
     <div ref={drop} className="ant-row modal-fields-row">
       {cards.map(card => (
-        <Col key={card.uuid} span={card.type !== 'textarea' ? _cols : 24}>
+        <Col key={card.uuid} className={card.type === 'textarea' ? 'textarea' + setting.cols : ''} span={card.type !== 'textarea' ? _cols : 24}>
           <Card
-            id={`${card.uuid}`}
+            id={card.uuid}
+            cols={setting.cols}
             card={card}
             moveCard={moveCard}
             editCard={editCard}
diff --git a/src/templates/modalconfig/dragelement/index.scss b/src/templates/modalconfig/dragelement/index.scss
index 248e718..a61965a 100644
--- a/src/templates/modalconfig/dragelement/index.scss
+++ b/src/templates/modalconfig/dragelement/index.scss
@@ -15,4 +15,8 @@
 }
 .modal-fields-row {
   padding-bottom: 35px;
+  .ant-col {
+    padding-left: 12px;
+    padding-right: 12px;
+  }
 }
\ No newline at end of file
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index 00530a6..b3cdf2a 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -374,7 +374,7 @@
             text: this.state.dict['header.form.link']
           }, {
             value: 'fileupload',
-            text: '鏂囦欢涓婁紶'
+            text: this.state.dict['header.form.fileupload']
           }, {
             value: 'date',
             text: this.state.dict['header.form.dateday']
@@ -386,10 +386,10 @@
             text: this.state.dict['header.form.datetime']
           }, {
             value: 'textarea',
-            text: '澶氳鏂囨湰'
+            text: this.state.dict['header.form.textarea']
           }, {
             value: 'funcvar',
-            text: '鍑芥暟鍙橀噺'
+            text: this.state.dict['header.form.funcvar']
           }]
         },
         {
@@ -537,7 +537,7 @@
         {
           type: 'multiselect',
           key: 'linkSubField',
-          label: '鍏宠仈琛ㄥ崟',
+          label: this.state.dict['header.form.linkForm'],
           initVal: card.linkSubField || [],
           options: _inputfields
         }
@@ -902,7 +902,7 @@
             orderBy: '',
             orderType: 'asc',
             readonly: 'false',
-            required: 'false'
+            required: 'true'
           }
   
           items.push(newcard)
diff --git a/src/templates/modalconfig/index.scss b/src/templates/modalconfig/index.scss
index 04547e8..21270e3 100644
--- a/src/templates/modalconfig/index.scss
+++ b/src/templates/modalconfig/index.scss
@@ -211,7 +211,6 @@
             display: flex;
             margin-bottom: 0px;
             .ant-form-item-label {
-              // width: 100px;
               height: 40px;
               label {
                 width: 100%;
@@ -223,7 +222,6 @@
               }
             }
             .ant-form-item-control-wrapper {
-              flex: 1 1;
               .ant-select {
                 width: 100%;
                 margin-top: 4px;
@@ -245,20 +243,45 @@
                 opacity: 0;
               }
             }
+            .ant-col-cuslabel {
+              width: 10.5%;
+            }
+            .ant-col-cuswrap {
+              width: 89.5%;
+            }
           }
           .edit {
             position: absolute;
-            left: calc(33% - 100px);
+            left: calc(33% - 70px);
             top: 0px;
             color: #1890ff;
             cursor: pointer;
             display: none;
           }
           .edit.close {
-            left: calc(33% - 75px);
+            left: calc(33% - 45px);
             color: #ff4d4f;
           }
         }
+        .ant-col.textarea2 {
+          padding-left: 7px;
+          .page-card {
+            .edit {
+              left: calc(17% - 70px);
+            }
+            .edit.close {
+              left: calc(17% - 45px);
+            }
+          }
+        }
+        .ant-col.textarea3 .page-card {
+          .edit {
+            left: calc(11% - 70px);
+          }
+          .edit.close {
+            left: calc(11% - 45px);
+          }
+        }
         .page-card:hover {
           .edit {
             display: inline-block;
diff --git a/src/templates/tableshare/dragelement/index.jsx b/src/templates/tableshare/dragelement/index.jsx
index 13d1460..17f483d 100644
--- a/src/templates/tableshare/dragelement/index.jsx
+++ b/src/templates/tableshare/dragelement/index.jsx
@@ -9,6 +9,7 @@
 
 const Container = ({list, setting, gridBtn, type, placeholder, handleList, handleMenu, deleteMenu, copyElement, profileMenu, handleGridBtn, showfield }) => {
   let target = null
+  
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -78,43 +79,29 @@
         }
         
         newcard.label = 'label'
-        newcard.field = ''
         newcard.initval = ''
         newcard.type = item.subType
         newcard.resourceType = '0'
         newcard.options = []
-        newcard.dataSource = ''
         newcard.setAll = 'false'
-        newcard.linkField = ''
-        newcard.valueField = ''
-        newcard.valueText = ''
-        newcard.orderBy = ''
         newcard.orderType = 'asc'
         newcard.match = _match
         newcard.display = 'dropdown'
       } else if (item.type === 'action') {
         newcard.label = 'button'
-        newcard.innerFunc = ''
-        newcard.outerFunc = ''
-        newcard.sql = ''
         newcard.sqlType = ''
         newcard.Ot = 'requiredSgl'
         newcard.OpenType = item.subType
         newcard.tabType = 'SubTable'
-        newcard.linkTab = ''
         newcard.icon = ''
         newcard.class = 'default'
         newcard.intertype = 'inner'
-        newcard.interface = ''
         newcard.method = 'POST'
         newcard.position = 'toolbar'
         newcard.execSuccess = 'grid'
         newcard.execError = 'never'
         newcard.popClose = 'never'
         newcard.errorTime = 15
-        newcard.callbackFunc = ''
-        newcard.pageTemplate = ''
-        newcard.url = ''
         newcard.verify = null
 
         if (item.subType === 'excelIn' || item.subType === 'excelOut') {
@@ -144,12 +131,8 @@
 
       const { index: overIndex } = findCard(`${targetId}`)
       let targetIndex = overIndex
-      // if (!target) {
+
       targetIndex++
-      // }
-      // if (targetIndex < 0) {
-      //   targetIndex = 0
-      // }
 
       const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
       setCards(_cards)
diff --git a/src/utils/option.js b/src/utils/option.js
index 8d529e6..5068926 100644
--- a/src/utils/option.js
+++ b/src/utils/option.js
@@ -25,7 +25,8 @@
     innerMessage: '鍐呴儴鍑芥暟鍚嶇О鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶅拰涓嬪垝绾匡紝涓斾互鎸囧畾瀛楃寮�濮嬨��'
   },
   textarea: {
-    max: 1024
+    max: 1024,
+    message: '闀挎枃鏈渶澶�1024涓瓧绗︺��'
   }
 }
 

--
Gitblit v1.8.0