From 7b01bec1609710729a868093ad69484ebea82d80 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 20 十月 2020 10:16:26 +0800
Subject: [PATCH] 2020-10-20

---
 src/tabviews/treepage/index.jsx                                                    |    4 
 src/templates/zshare/modalform/index.jsx                                           |  194 +++++-
 src/templates/zshare/modalform/fieldtable/index.jsx                                |  308 +++++++++++
 src/templates/zshare/modalform/fieldtable/index.scss                               |   52 +
 src/menu/components/card/cardcomponent/settingform/index.jsx                       |    2 
 src/menu/actioncomponent/formconfig.jsx                                            |    2 
 src/tabviews/zshare/checkCard/index.jsx                                            |   56 ++
 src/menu/components/card/cardcellcomponent/dragaction/index.jsx                    |    1 
 src/templates/modalconfig/checkCard/index.scss                                     |   19 
 src/tabviews/calendar/index.jsx                                                    |    5 
 src/templates/modalconfig/checkCard/index.jsx                                      |   74 ++
 src/templates/modalconfig/index.jsx                                                |  112 ---
 src/templates/modalconfig/dragelement/index.jsx                                    |   69 +
 src/templates/modalconfig/dragelement/card.jsx                                     |   26 
 src/tabviews/custom/components/card/data-card/index.jsx                            |    1 
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx                     |    2 
 src/mob/colorsketch/index.jsx                                                      |   17 
 src/templates/modalconfig/index.scss                                               |   14 
 src/menu/components/card/cardcellcomponent/index.jsx                               |    3 
 src/templates/zshare/formconfig.jsx                                                |  146 ++++-
 src/templates/zshare/modalform/datatable/index.jsx                                 |  368 +++++++++++++
 src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx |    2 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                          |    2 
 src/templates/zshare/modalform/index.scss                                          |   24 
 src/tabviews/custom/index.jsx                                                      |    3 
 src/templates/modalconfig/source.jsx                                               |    6 
 src/templates/zshare/createinterface/index.jsx                                     |   11 
 src/menu/components/card/data-card/wrapsetting/settingform/index.jsx               |    2 
 src/templates/zshare/modalform/datatable/index.scss                                |   57 ++
 src/tabviews/zshare/fileupload/index.jsx                                           |   22 
 src/templates/zshare/modalform/modaleditable/index.jsx                             |   26 
 src/templates/zshare/modalform/modaleditable/index.scss                            |    7 
 src/menu/components/tabs/tabsetting/settingform/index.jsx                          |    2 
 src/tabviews/zshare/checkCard/index.scss                                           |    3 
 34 files changed, 1,393 insertions(+), 249 deletions(-)

diff --git a/src/menu/actioncomponent/formconfig.jsx b/src/menu/actioncomponent/formconfig.jsx
index 1e55179..01043a7 100644
--- a/src/menu/actioncomponent/formconfig.jsx
+++ b/src/menu/actioncomponent/formconfig.jsx
@@ -299,7 +299,7 @@
       precision: 0,
       label: '瀹藉害',
       initVal: card.width || 12,
-      tooltip: '姣忚绛夊垎涓�24浠姐��',
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       forbid: type !== 'card',
       required: true
     },
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
index 0c879f2..845cedf 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -44,7 +44,6 @@
 
   const doubleClickCard = id => {
     const { card } = findCard(id)
-    console.log(card)
     if (card.OpenType === 'pop') {
       handleSubConfig(card)
     }
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 7a33eda..482842f 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -171,7 +171,7 @@
       precision: 0,
       label: '瀹藉害',
       initVal: card.width || 12,
-      tooltip: '姣忚绛夊垎涓�24浠姐��',
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       required: true
     },
     {
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 3c7c241..6d5917b 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -463,7 +463,6 @@
     const { elements } = this.state
     
     this.verifyRef.handleConfirm().then(res => {
-      console.log(res)
       let _elements = elements.map(cell => {
         if (cell.uuid === res.uuid) {
           res.eleType = 'button'
@@ -484,7 +483,7 @@
   }
 
   handleSubConfig = (item) => {
-    console.log(item)
+
   }
 
   render() {
diff --git a/src/menu/components/card/cardcomponent/settingform/index.jsx b/src/menu/components/card/cardcomponent/settingform/index.jsx
index 8907f5d..2d570db 100644
--- a/src/menu/components/card/cardcomponent/settingform/index.jsx
+++ b/src/menu/components/card/cardcomponent/settingform/index.jsx
@@ -44,7 +44,7 @@
           <Row gutter={24}>
             <Col span={12}>
               <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒�24浠姐��">
+                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
                   <Icon type="question-circle" />
                   鍗$墖瀹藉害
                 </Tooltip>
diff --git a/src/menu/components/card/data-card/wrapsetting/settingform/index.jsx b/src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
index ce3bd88..0d87bc9 100644
--- a/src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
+++ b/src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
@@ -62,7 +62,7 @@
             </Col>
             <Col span={12}>
               <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒�24浠姐��">
+                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
                   <Icon type="question-circle" />
                   瀹藉害
                 </Tooltip>
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index b517422..e49d7a3 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -57,7 +57,7 @@
       key: 'width',
       label: '瀹藉害',
       initVal: card.width,
-      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒�24浠姐��',
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       min: 1,
       max: 24,
       decimal: 0,
diff --git a/src/menu/components/tabs/tabsetting/settingform/index.jsx b/src/menu/components/tabs/tabsetting/settingform/index.jsx
index 8e99efa..76976c4 100644
--- a/src/menu/components/tabs/tabsetting/settingform/index.jsx
+++ b/src/menu/components/tabs/tabsetting/settingform/index.jsx
@@ -69,7 +69,7 @@
             </Col>
             <Col span={12}>
               <Form.Item label={
-                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒�24浠姐��">
+                <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
                   <Icon type="question-circle" />
                   瀹藉害
                 </Tooltip>
diff --git a/src/mob/colorsketch/index.jsx b/src/mob/colorsketch/index.jsx
index 4f588d8..69f0d19 100644
--- a/src/mob/colorsketch/index.jsx
+++ b/src/mob/colorsketch/index.jsx
@@ -19,7 +19,22 @@
     onChange: PropTypes.func
   }
   state = {
-    color: this.props.defaultValue || this.props.value,
+    color: '',
+  }
+
+  UNSAFE_componentWillMount () {
+    const { defaultValue, value } = this.props
+    let initVal = ''
+
+    if (this.props['data-__meta']) {
+      initVal = this.props['data-__meta'].initialValue
+    } else if (defaultValue) {
+      initVal = defaultValue
+    } else if (value) {
+      initVal = value
+    }
+    
+    this.setState({color: initVal})
   }
 
   handleChange = (color) => {
diff --git a/src/tabviews/calendar/index.jsx b/src/tabviews/calendar/index.jsx
index b64ab9b..9bd3ce9 100644
--- a/src/tabviews/calendar/index.jsx
+++ b/src/tabviews/calendar/index.jsx
@@ -562,6 +562,7 @@
   }
 
   render() {
+    const { menuType } = this.props
     const { BID, searchlist, loadingview, viewlost, config, loading, data, triggerTime } = this.state
 
     return (
@@ -572,13 +573,13 @@
             BID={BID}
             dict={this.state.dict}
             searchlist={searchlist}
-            menuType={this.props.menuType}
+            menuType={menuType}
             dataManager={this.props.dataManager}
             refreshdata={this.refreshbysearch}
           /> : null
         }
         {config && config.calendar ? <CalendarComponent calendar={config.calendar} loading={loading} data={data} triggerDate={this.triggerDate} changeDate={this.changeDate}/> : null}
-        {options.sysType !== 'cloud' ? <Button
+        {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button
           icon="copy"
           shape="circle"
           className="common-table-copy"
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index 3d1c86d..06a8198 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -37,7 +37,6 @@
 
   UNSAFE_componentWillMount () {
     let _config = fromJS(this.props.config).toJS()
-    console.log(_config)
 
     this.setState({
       config: _config,
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index e361d2b..c1a736d 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -469,13 +469,14 @@
 
 
   render() {
+    const { menuType } = this.props
     const { loadingview, viewlost, config } = this.state
 
     return (
       <div className="custom-page-wrap" id={this.state.ContainerId} style={config ? config.style : null}>
         {loadingview && <Spin size="large" />}
         <Row>{this.getComponents()}</Row>
-        {options.sysType !== 'cloud' ? <Button
+        {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button
           icon="copy"
           shape="circle"
           className="common-table-copy"
diff --git a/src/tabviews/treepage/index.jsx b/src/tabviews/treepage/index.jsx
index 0e313b2..9e91b82 100644
--- a/src/tabviews/treepage/index.jsx
+++ b/src/tabviews/treepage/index.jsx
@@ -754,6 +754,7 @@
   }
 
   render() {
+    const { menuType } = this.props
     const { setting, loadingview, viewlost, config, triggerBtn, userConfig, tabActive, tabgroups, treeNodes, treedata, expandedKeys, selectedKeys } = this.state
 
     return (
@@ -822,8 +823,7 @@
             )}
           </Col>
         </Row> : null}
-        
-        {options.sysType !== 'cloud' ? <Button
+        {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button
           icon="copy"
           shape="circle"
           className="tree-page-copy"
diff --git a/src/tabviews/zshare/checkCard/index.jsx b/src/tabviews/zshare/checkCard/index.jsx
new file mode 100644
index 0000000..ff76da2
--- /dev/null
+++ b/src/tabviews/zshare/checkCard/index.jsx
@@ -0,0 +1,56 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+// import { fromJS } from 'immutable'
+import { Col, Row } from 'antd'
+
+import './index.scss'
+
+
+class CheckCard extends Component {
+  static propTpyes = {
+    multiple: PropTypes.bool,    // 鏄惁鍙閫�
+    width: PropTypes.number,     // 瀹藉害
+    display: PropTypes.string,   // 鏄剧ず涓猴細text锛堟枃鏈級銆乸icture锛堝浘鐗囷級
+    fields: PropTypes.array,     // 瀛楁闆�
+    options: PropTypes.array,    // 鏁版嵁鍒楄〃
+    onChange: PropTypes.func,    // 鏁版嵁鍒囨崲
+  }
+
+  state = {
+    selectKeys: null,       // 閫変腑鏁版嵁id
+  }
+
+  UNSAFE_componentWillMount () {
+
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+
+  }
+
+  getCards = () => {
+    const { display, options, fields } = this.props
+    if (display === 'picture') {
+      return options.map(item => {
+        <Col>
+          <div>
+            {fields.map(col => {
+              return <span></span>
+            })}
+          </div>
+        </Col>
+      })
+    } else {
+      return <Col></Col>
+    }
+  }
+
+  render() {
+
+    return (
+      <Row gutter={24}>{this.getCards()}</Row>
+    )
+  }
+}
+
+export default CheckCard
\ No newline at end of file
diff --git a/src/tabviews/zshare/checkCard/index.scss b/src/tabviews/zshare/checkCard/index.scss
new file mode 100644
index 0000000..4e9c6be
--- /dev/null
+++ b/src/tabviews/zshare/checkCard/index.scss
@@ -0,0 +1,3 @@
+.check-card-edit-box {
+ 
+}
\ No newline at end of file
diff --git a/src/tabviews/zshare/fileupload/index.jsx b/src/tabviews/zshare/fileupload/index.jsx
index 4f8f0a8..0207a36 100644
--- a/src/tabviews/zshare/fileupload/index.jsx
+++ b/src/tabviews/zshare/fileupload/index.jsx
@@ -8,11 +8,6 @@
 import Utils from '@/utils/utils.js'
 import './index.scss'
 
-// let Url = '/Upload'
-// if (process.env.NODE_ENV === 'production') {
-//   Url = document.location.origin + '/' + window.GLOB.service + 'zh-CN/Home/Upload'
-// }
-
 let service = ''
 if (process.env.NODE_ENV === 'production') {
   service = document.location.origin + '/' + window.GLOB.service
@@ -22,7 +17,7 @@
 
 class FileUpload extends Component {
   static propTpyes = {
-    value: PropTypes.array,    // 鎸夐挳淇℃伅銆佽〃鍗曞垪琛�
+    value: PropTypes.array,    // 鏂囦欢鏁扮粍
     maxFile: PropTypes.any,    // 鏈�澶ф枃浠舵暟
     fileType: PropTypes.string // 鏂囦欢鏄剧ず绫诲瀷
   }
@@ -81,12 +76,6 @@
       duration: 5
     })
   }
-
-  // getExtraData = () => {
-  //   return {
-  //     RootPath: 'Content/images/upload/'
-  //   }
-  // }
 
   shardupload = (params) => {
     let param = params.chunks.shift()
@@ -229,7 +218,6 @@
       chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
     }
 
-    // loadNext()
     return false
   }
 
@@ -262,16 +250,18 @@
       multiple: false,
       onChange: this.onChange,
       onRemove: this.onRemove,
-      // data: this.getExtraData,
       beforeUpload: this.beforeUpload,
       className: uploadable
     }
 
     return (
       <Upload {...props}>
-        <Button>
+        {fileType !== 'picture-card' ? <Button>
           <Icon type="upload" /> 鐐瑰嚮涓婁紶
-        </Button>
+        </Button> : null}
+        {fileType === 'picture-card' ? <span style={{whiteSpace: 'nowrap'}}>
+          <Icon type="upload" /> 鐐瑰嚮涓婁紶
+        </span> : null}
         {showprogress ? <Progress percent={percent} size="small" /> : null}
       </Upload>
     )
diff --git a/src/templates/modalconfig/checkCard/index.jsx b/src/templates/modalconfig/checkCard/index.jsx
new file mode 100644
index 0000000..bc378bf
--- /dev/null
+++ b/src/templates/modalconfig/checkCard/index.jsx
@@ -0,0 +1,74 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+// import { fromJS } from 'immutable'
+import { Col, Row } from 'antd'
+
+import './index.scss'
+
+
+class CheckCard extends Component {
+  static propTpyes = {
+    multiple: PropTypes.bool,    // 鏄惁鍙閫�
+    ratio: PropTypes.string,     // 鍥剧墖姣斾緥
+    width: PropTypes.number,     // 瀹藉害
+    display: PropTypes.string,   // 鏄剧ず涓猴細text锛堟枃鏈級銆乸icture锛堝浘鐗囷級
+    fields: PropTypes.array,     // 瀛楁闆�
+    options: PropTypes.array,    // 鏁版嵁鍒楄〃
+    onChange: PropTypes.func,    // 鏁版嵁鍒囨崲
+  }
+
+  state = {
+    selectKeys: null,       // 閫変腑鏁版嵁id
+  }
+
+  UNSAFE_componentWillMount () {
+
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+
+  }
+
+  getCards = () => {
+    const { display, width, options, fields, ratio } = this.props
+
+    let paddingTop = '100%'
+    if (ratio === '4:3') {
+      paddingTop = '75%'
+    } else if (ratio === '3:2') {
+      paddingTop = '66.7%'
+    } else if (ratio === '16:9') {
+      paddingTop = '56.25%'
+    }
+
+    if (display !== 'picture') {
+      return options.map(item => {
+        return <Col span={width} key={item.key}>
+          <div className="card-cell">
+            {fields.map(col => {
+              return <span key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+            })}
+          </div>
+        </Col>
+      })
+    } else {
+      return options.map(item => {
+        return <Col span={width} key={item.key}>
+          <div className="card-pic-cell" style={{paddingTop, backgroundImage: `url(${item.$url})`}}>
+          </div>
+        </Col>
+      })
+    }
+  }
+
+  render() {
+
+    return (
+      <div className="check-card-edit-box" style={{marginTop: '10px'}}>
+        <Row gutter={12}>{this.getCards()}</Row>
+      </div>
+    )
+  }
+}
+
+export default CheckCard
\ No newline at end of file
diff --git a/src/templates/modalconfig/checkCard/index.scss b/src/templates/modalconfig/checkCard/index.scss
new file mode 100644
index 0000000..fc1475f
--- /dev/null
+++ b/src/templates/modalconfig/checkCard/index.scss
@@ -0,0 +1,19 @@
+.check-card-edit-box {
+  .card-cell {
+    border: 1px solid #bcbcbc;
+    border-radius: 4px;
+    padding: 6px;
+    span {
+      display: block;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  }
+  .card-pic-cell {
+    border: 1px solid #bcbcbc;
+    border-radius: 4px;
+    background-size: cover;
+    background-position: center;
+  }
+}
\ No newline at end of file
diff --git a/src/templates/modalconfig/dragelement/card.jsx b/src/templates/modalconfig/dragelement/card.jsx
index 9fb9bb1..8d78aab 100644
--- a/src/templates/modalconfig/dragelement/card.jsx
+++ b/src/templates/modalconfig/dragelement/card.jsx
@@ -2,12 +2,14 @@
 import { useDrag, useDrop } from 'react-dnd'
 import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox } from 'antd'
 import moment from 'moment'
+
+import CheckCard from '../checkCard'
 import './index.scss'
 
 const { MonthPicker } = DatePicker
 const { TextArea } = Input
 
-const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, copyCard, hasDrop }) => {
+const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, copyCard }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: 'form', id, originalIndex },
@@ -18,9 +20,11 @@
   const [, drop] = useDrop({
     accept: 'form',
     canDrop: () => true,
-    drop: ({ id: draggedId, originalIndex }) => {
+    drop: (item) => {
+      const { id: draggedId, originalIndex } = item
+
       if (originalIndex === undefined) {
-        hasDrop(card)
+        item.dropTargetId = id
       } else if (draggedId) {
         if (draggedId !== id) {
           const { index: overIndex } = findCard(id)
@@ -58,7 +62,13 @@
   }
   let labelCol = 'ant-col-sm-8'
   let wrapCol = 'ant-col-sm-16'
-  if (card.type === 'textarea') {
+  let isEntireLine = false
+
+  if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard'].includes(card.type)) {
+    isEntireLine = true
+  }
+
+  if (isEntireLine) {
     if (cols === '2') {
       labelCol = 'ant-col-sm-4'
       wrapCol = 'ant-col-sm-20'
@@ -108,6 +118,10 @@
       <Checkbox value="C">C</Checkbox>
       <Checkbox value="D">D</Checkbox>
     </Checkbox.Group>)
+  } else if (card.type === 'hint') {
+    formItem = <div style={{marginTop: '10px', color: 'rgba(0, 0, 0, 0.85)'}}>{card.message}</div>
+  } else if (card.type === 'checkcard') {
+    formItem = <CheckCard width={card.width} ratio={card.ratio} display={card.display} fields={card.fields} options={card.options} />
   }
 
   return (
@@ -122,7 +136,9 @@
         <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 ' + labelCol}>
-              <label title={card.label}>{card.label}</label>
+              {card.label ? <label className={card.required === 'true' ? 'required' : ''}>{card.tooltip ? 
+                <Icon type="question-circle" /> : null}
+                {card.label}</label> : null}
             </div>
             <div className={'ant-col ant-form-item-control-wrapper ant-col-xs-24 ' + wrapCol}>
               {formItem}
diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx
index e1937b7..20ddba6 100644
--- a/src/templates/modalconfig/dragelement/index.jsx
+++ b/src/templates/modalconfig/dragelement/index.jsx
@@ -8,8 +8,6 @@
 import './index.scss'
 
 const Container = ({list, group, setting, placeholder, handleList, handleForm, closeForm }) => {
-  let target = null
-
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -39,7 +37,7 @@
 
   const editCard = id => {
     const { card } = findCard(id)
-    handleForm(card, 'edit')
+    handleForm(card)
   }
 
   const closeCard = id => {
@@ -48,12 +46,34 @@
   }
 
   const copyCard = id => {
-    const { card } = findCard(id)
-    handleForm(card, 'copy')
-  }
-  
-  const hasDrop = (item) => {
-    target = item
+    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 = 'form'
+
+    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)
+
+    if (!group) {
+      handleList(_cards, null, null, _card)
+    } else {
+      handleList(_cards, group, null, _card)
+    }
   }
 
   const [, drop] = useDrop({
@@ -79,17 +99,17 @@
       newcard.required = 'true'
       newcard.focus = true
 
-      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
-      if (target) {
-        targetId = target.uuid
+      let targetId = '0'
+
+      if (item.dropTargetId) {
+        targetId = item.dropTargetId
+      } else if (cards.length > 0) {
+        targetId = cards[cards.length - 1].uuid
       }
 
-      const { index: overIndex } = findCard(`${targetId}`)
-      let targetIndex = overIndex
+      const { index: overIndex } = findCard(`${targetId}`) // cards涓虹┖鏃� overIndex 涓� -1
+      const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] })
 
-      targetIndex++
-
-      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
       setCards(_cards)
 
       if (!group) {
@@ -97,8 +117,6 @@
       } else {
         handleList(_cards, group, null, newcard)
       }
-
-      target = null
     }
   })
 
@@ -106,8 +124,14 @@
   
   return (
     <div ref={drop} className="ant-row modal-fields-row">
-      {cards.map(card => (
-        <Col key={card.uuid} className={card.type === 'textarea' ? 'textarea' + setting.cols : ''} span={card.type !== 'textarea' ? _cols : 24}>
+      {cards.map(card => {
+        let isEntireLine = false
+
+        if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard'].includes(card.type)) {
+          isEntireLine = true
+        }
+        
+        return <Col key={card.uuid} className={isEntireLine ? 'textarea' + setting.cols : ''} span={isEntireLine ? 24 : _cols}>
           <Card
             id={card.uuid}
             cols={setting.cols}
@@ -117,10 +141,9 @@
             closeCard={closeCard}
             copyCard={copyCard}
             findCard={findCard}
-            hasDrop={hasDrop}
           />
         </Col>
-      ))}
+      })}
       {cards.length === 0 &&
         <div className="modal-drawarea-placeholder">
           {placeholder}
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index 53313ee..151df90 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -49,7 +49,6 @@
     dict: CommonDict,      // 瀛楀吀
     config: null,          // 椤甸潰閰嶇疆锛屽寘鎷ā鏉跨被鍨嬨�佹ā鎬佹璁剧疆銆佹坊鍔犺〃鍚嶃�佽〃鍗曞垪琛�
     visible: false,        // 琛ㄥ崟缂栬緫妯℃�佹锛屾樉绀烘帶鍒�
-    modalType: null,       // 琛ㄥ崟缂栬緫绫诲瀷锛岀紪杈戞垨澶嶅埗
     tableVisible: false,   // 鏁版嵁琛ㄥ瓧娈靛垪琛ㄦā鎬佹锛屾樉绀烘帶鍒�
     tableColumns: [],      // 琛ㄦ牸瀛楁鍚嶅垪琛�
     fields: null,          // 琛ㄥ崟锛屽彲閫夊瓧娈碉紙鍘婚噸鍚庯級
@@ -352,32 +351,9 @@
    * 2銆佷繚瀛樼紪杈戦」-card
    * 3銆佽缃紪杈戝弬鏁伴」-formlist
    */
-  handleForm = (_card, type) => {
+  handleForm = (_card) => {
     const {menu, tabConfig, subTabConfig} = this.props
     let card = JSON.parse(JSON.stringify(_card))
-
-    if (type === 'copy') {
-      card.originUuid = card.uuid
-      card.uuid = Utils.getuuid()
-      card.focus = true
-
-      // 澶嶅埗鍒板壀鍒囨澘
-      let oInput = document.createElement('input')
-      let val = JSON.parse(JSON.stringify(card))
-      val.copyType = 'form'
-      val.uuid = Utils.getuuid()
-
-      delete val.originUuid
-
-      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 { config } = this.state
     let _inputfields = []
     let _linkableFields = []
@@ -472,7 +448,6 @@
 
     this.setState({
       visible: true,
-      modalType: type,
       card: card,
       formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, !!this.props.editTab, roleList)
     })
@@ -485,70 +460,14 @@
    * 3銆侀�氳繃loading鍒锋柊
    */
   handleSubmit = () => {
-    const { card, modalType } = this.state
-
     this.formRef.handleConfirm().then(res => {
       let _config = JSON.parse(JSON.stringify(this.state.config))
       let fieldrepet = false // 瀛楁閲嶅
       let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
 
-      if (modalType === 'copy' && card.originUuid) {
-        if (_config.groups.length > 0) {
-          _config.groups = _config.groups.map(group => {
-            let _index = null
-            group.sublist.forEach((item, index) => {
-              if (item.uuid === card.originUuid) {
-                _index = index
-              }
-
-              if (item.uuid !== res.uuid && item.field === res.field) {
-                fieldrepet = true
-              } else if (item.uuid !== res.uuid && item.label === res.label) {
-                labelrepet = true
-              }
-            })
-
-            if (_index !== null) {
-              group.sublist.splice(_index + 1, 0, res)
-            }
-
-            return group
-          })
-        } else {
-          let _index = null
-          _config.fields.forEach((item, index) => {
-            if (item.uuid === card.originUuid) {
-              _index = index
-            }
-
-            if (item.uuid !== res.uuid && item.field === res.field) {
-              fieldrepet = true
-            } else if (item.uuid !== res.uuid && item.label === res.label) {
-              labelrepet = true
-            }
-          })
-
-          _config.fields.splice(_index + 1, 0, res)
-        }
-      } else {
-        if (_config.groups.length > 0) {
-          _config.groups.forEach(group => {
-            group.sublist = group.sublist.map(item => {
-              if (item.uuid !== res.uuid && item.field === res.field) {
-                fieldrepet = true
-              } else if (item.uuid !== res.uuid && item.label === res.label) {
-                labelrepet = true
-              }
-
-              if (item.uuid === res.uuid) {
-                return res
-              } else {
-                return item
-              }
-            })
-          })
-        } else {
-          _config.fields = _config.fields.map(item => {
+      if (_config.groups.length > 0) {
+        _config.groups.forEach(group => {
+          group.sublist = group.sublist.map(item => {
             if (item.uuid !== res.uuid && item.field === res.field) {
               fieldrepet = true
             } else if (item.uuid !== res.uuid && item.label === res.label) {
@@ -561,7 +480,21 @@
               return item
             }
           })
-        }
+        })
+      } else {
+        _config.fields = _config.fields.map(item => {
+          if (item.uuid !== res.uuid && item.field === res.field) {
+            fieldrepet = true
+          } else if (item.uuid !== res.uuid && item.label === res.label) {
+            labelrepet = true
+          }
+
+          if (item.uuid === res.uuid) {
+            return res
+          } else {
+            return item
+          }
+        })
       }
 
       if (fieldrepet) {
@@ -607,7 +540,6 @@
             this.setState({
               sqlVerifing: false,
               config: _config,
-              modalType: null,
               card: null,
               visible: false
             })
@@ -622,7 +554,6 @@
       } else {
         this.setState({
           config: _config,
-          modalType: null,
           card: null,
           visible: false
         })
@@ -1299,9 +1230,10 @@
           </div>
         </DndProvider>
         <Modal
-          title={this.state.modalType !== 'copy' ? this.state.dict['model.edit'] : this.state.dict['header.modal.form.copy']}
+          title={this.state.dict['model.edit']}
           visible={this.state.visible}
-          width={800}
+          width={850}
+          maskClosable={false}
           onCancel={this.editModalCancel}
           onOk={this.handleSubmit}
           confirmLoading={this.state.sqlVerifing}
diff --git a/src/templates/modalconfig/index.scss b/src/templates/modalconfig/index.scss
index f09e697..2969e25 100644
--- a/src/templates/modalconfig/index.scss
+++ b/src/templates/modalconfig/index.scss
@@ -198,6 +198,20 @@
                 text-overflow: ellipsis;
                 white-space: nowrap;
               }
+              label.required::before {
+                display: inline-block;
+                margin-right: 4px;
+                color: #f5222d;
+                font-size: 14px;
+                font-family: SimSun, sans-serif;
+                line-height: 1;
+                content: '*';
+              }
+              .anticon-question-circle {
+                color: #c49f47;
+                margin-right: 3px;
+                line-height: 40px;
+              }
             }
             .ant-form-item-control-wrapper {
               .ant-select {
diff --git a/src/templates/modalconfig/source.jsx b/src/templates/modalconfig/source.jsx
index d3ec36b..0148cdb 100644
--- a/src/templates/modalconfig/source.jsx
+++ b/src/templates/modalconfig/source.jsx
@@ -158,6 +158,12 @@
   },
   {
     type: 'form',
+    label: '鎻愮ず',
+    subType: 'hint',
+    url: ''
+  },
+  {
+    type: 'form',
     label: CommonDict['model.form.color'],
     subType: 'color',
     url: ''
diff --git a/src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx b/src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx
index 27ba28c..1f161ae 100644
--- a/src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx
@@ -426,7 +426,7 @@
             </Col>
             <Col span={12}>
               <Form.Item label={
-                <Tooltip placement="topLeft" title={'姣忚鍒嗕负24浠斤紝鏍戝舰姣斾緥鍙缃负2-12锛堟渶澶�50%锛�'}>
+                <Tooltip placement="topLeft" title={'鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒楋紝鏍戝舰姣斾緥鍙缃负2-12锛堟渶澶�50%锛�'}>
                   <Icon type="question-circle" />
                   瀹藉害
                 </Tooltip>
diff --git a/src/templates/zshare/createinterface/index.jsx b/src/templates/zshare/createinterface/index.jsx
index 89a9089..34364f1 100644
--- a/src/templates/zshare/createinterface/index.jsx
+++ b/src/templates/zshare/createinterface/index.jsx
@@ -360,7 +360,7 @@
         type: 'radio',
         key: 'TryType',
         label: '浜嬪姟',
-        initval: 'N',
+        initval: 'Y',
         required: true,
         options: [{
           value: 'Y',
@@ -569,14 +569,9 @@
     }).then(res => {
       if (res === false) return res
 
-      if (window.GLOB.mainSystemApi) {
-        _mainParam.rduri = window.GLOB.mainSystemApi
-
-        return Api.getLocalConfig(_mainParam)
-      }
-      return 'success'
+      return Api.getCloudConfig(_mainParam)
     }).then(res => {
-      if (res === false || res === 'success') return res
+      if (res === false) return res
 
       if (!res.status) {
         notification.warning({
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index 2632de6..911b47b 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -226,7 +226,7 @@
       min: 2,
       max: 12,
       label: '瀹藉害',
-      tooltip: '姣忚鍒嗕负24浠斤紝鏍戝舰姣斾緥鍙缃负2-12锛堟渶澶�50%锛�',
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒楋紝鏍戝舰姣斾緥鍙缃负2-12锛堟渶澶�50%锛�',
       initVal: setting.width || 5,
       required: true
     },
@@ -529,7 +529,7 @@
       min: 1,
       max: 24,
       label: Formdict['header.form.ratio'],
-      tooltip: '姣忚鍒嗕负24浠斤紝姣斾緥鍙缃负1-24',
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       initVal: card.ratio,
       required: false
     },
@@ -1356,7 +1356,7 @@
       max: 24,
       decimal: 0,
       label: '鍥捐〃瀹藉害',
-      tooltip: '姣忚绛夊垎涓�24鍒楋紝24鍗充负100%銆�',
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
       initVal: card.width || 24,
       required: true
     },
@@ -1398,7 +1398,7 @@
       max: card.widthType === 'absolute' ? 1000 : 24,
       decimal: 0,
       label: '鍗$墖瀹藉害',
-      tooltip: '绫诲瀷涓烘瘮渚嬫椂锛岃寖鍥�1-24锛�24鍗充负100%锛涚被鍨嬩负缁濆鍊硷紝鑼冨洿50-1000銆�',
+      tooltip: '绫诲瀷涓烘瘮渚嬫椂锛屾爡鏍煎竷灞�锛屾瘡琛岀瓑鍒嗕负24鍒楋紱绫诲瀷涓虹粷瀵瑰�硷紝鑼冨洿50-1000銆�',
       initVal: card.cardWidth || 6,
       hidden: true,
       required: true
@@ -1771,7 +1771,7 @@
     })
   }
 
-  if (card.type === 'textarea' || card.type === 'fileupload' || card.type === 'multiselect') {
+  if (card.type === 'textarea' || card.type === 'fileupload' || card.type === 'multiselect' || card.type === 'checkbox') {
     _fieldlength = 512
   }
 
@@ -1841,6 +1841,9 @@
         value: 'textarea',
         text: Formdict['model.form.textarea']
       }, {
+        value: 'hint',
+        text: '鎻愮ず'
+      }, {
         value: 'color',
         text: Formdict['model.form.color']
       }, {
@@ -1856,6 +1859,14 @@
       tooltip: '涓嬫媺澶氶�変笌澶氶�夋锛屾坊鍔犲涓垵濮嬪�艰浣跨敤鈥�,鈥濆彿鍒嗛殧銆�',
       initVal: card.initval || '',
       required: false
+    },
+    {
+      type: 'textarea',
+      key: 'message',
+      label: '鎻愮ず淇℃伅',
+      initVal: card.message || '',
+      required: true,
+      readonly: false
     },
     {
       type: 'text',
@@ -1900,6 +1911,50 @@
       }]
     },
     {
+      type: 'number',
+      key: 'width',
+      label: '鍗$墖瀹藉害',
+      initVal: card.width || 4,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      required: true
+    },
+    {
+      type: 'text',
+      key: 'cardValField',
+      label: Formdict['header.form.valueField'],
+      initVal: card.cardValField || 'Value',
+      required: true,
+      readonly: false
+    },
+    {
+      type: 'text',
+      key: 'urlField',
+      label: '鍦板潃瀛楁',
+      initVal: card.urlField || '',
+      required: true,
+      readonly: false
+    },
+    {
+      type: 'radio',
+      key: 'ratio',
+      label: '鍥剧墖姣斾緥',
+      initVal: card.ratio || '1:1',
+      required: true,
+      options: [{
+        value: '1:1',
+        text: '1:1'
+      }, {
+        value: '3:2',
+        text: '3:2'
+      }, {
+        value: '4:3',
+        text: '4:3'
+      }, {
+        value: '16:9',
+        text: '16:9'
+      }]
+    },
+    {
       type: 'radio',
       key: 'setAll',
       label: Formdict['header.form.setAll'],
@@ -1913,18 +1968,26 @@
       }]
     },
     {
-      type: 'textarea',
-      key: 'dataSource',
-      label: Formdict['header.form.datasource'],
-      initVal: card.dataSource || '',
+      type: 'fields',
+      key: 'fields',
+      label: '瀛楁闆�',
+      initVal: card.fields || [],
       required: true,
       readonly: false
     },
     {
       type: 'options',
       key: 'options',
-      label: '',
+      label: '閫夐」',
       initVal: card.options || [],
+      required: true,
+      readonly: false
+    },
+    {
+      type: 'codemirror',
+      key: 'dataSource',
+      label: Formdict['header.form.datasource'],
+      initVal: card.dataSource || '',
       required: true,
       readonly: false
     },
@@ -1972,6 +2035,20 @@
       }, {
         value: 'desc',
         text: Formdict['header.form.desc']
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'multiple',
+      label: '鍙閫�',
+      initVal: card.multiple || 'false',
+      required: true,
+      options: [{
+        value: 'true',
+        text: '鏄�'
+      }, {
+        value: 'false',
+        text: '鍚�'
       }]
     },
     {
@@ -2028,25 +2105,6 @@
         value: 'letter&number',
         text: Formdict['header.form.letter&number']
       }]
-    },
-    {
-      type: 'select',
-      key: 'supField',
-      label: '涓婄骇琛ㄥ崟',
-      tooltip: '涓婄骇琛ㄥ崟涓轰笅鎷夐�夋嫨鎴栬仈鍔ㄨ彍鍗曪紝璁剧疆涓婄骇琛ㄥ崟鍚庯紝璇ヨ〃鍗曞彈鎺т簬涓婄骇鑿滃崟锛屾敞锛氬彈鎺у叧绯诲湪璇ヨ〃鍗曢殣钘忔椂澶辨晥銆�',
-      initVal: card.supField || '',
-      required: false,
-      readonly: false,
-      options: linksupFields
-    },
-    {
-      type: 'text',
-      key: 'supvalue',
-      label: '鏄剧ず鍊�',
-      tooltip: '閫夋嫨涓婄骇琛ㄥ崟鍚庯紝濉啓鏄剧ず鍊硷紝鍙湁涓婄骇琛ㄥ崟鍊间笌鏄剧ず鍊肩浉鍚屾椂锛岃琛ㄥ崟鎵嶄細鏄剧ず锛屾敞锛氬涓�肩敤閫楀彿鍒嗛殧銆�',
-      initVal: card.supvalue || '',
-      required: true,
-      readonly: false
     },
     {
       type: 'select',
@@ -2140,7 +2198,7 @@
     {
       type: 'radio',
       key: 'writein',
-      label: '鍐欏叆',
+      label: '鎵ц杩愮畻',
       tooltip: '琛ㄥ崟鎻愪氦鏃讹紝鏄惁灏嗚瀛楁鍊煎啓鍏ラ粯璁ql璇彞涓��',
       initVal: card.writein || 'true',
       options: [{
@@ -2193,13 +2251,41 @@
       }]
     },
     {
+      type: 'select',
+      key: 'supField',
+      label: '涓婄骇琛ㄥ崟',
+      tooltip: '涓婄骇琛ㄥ崟涓轰笅鎷夐�夋嫨銆佽仈鍔ㄨ彍鍗曘�佸崟閫夋鍙婂閫夋锛屾坊鍔犲悗璇ヨ〃鍗曟樉绀哄強闅愯棌灏嗗彈涓婄骇琛ㄥ崟鎺у埗锛屾敞锛氬彈鎺у叧绯诲湪璇ヨ〃鍗曢殣钘忔椂澶辨晥銆�',
+      initVal: card.supField || '',
+      required: false,
+      readonly: false,
+      options: linksupFields
+    },
+    {
+      type: 'text',
+      key: 'supvalue',
+      label: '鏄剧ず鍊�',
+      tooltip: '璇峰~鍐欐樉绀哄�硷紝鍙湁涓婄骇琛ㄥ崟鍊间笌鏄剧ず鍊肩浉鍚屾椂锛岃琛ㄥ崟鎵嶄細鏄剧ず锛屾敞锛氬涓�肩敤閫楀彿鍒嗛殧銆�',
+      initVal: card.supvalue || '',
+      required: true,
+      readonly: false
+    },
+    {
       type: 'multiselect',
       key: 'linkSubField',
       label: Formdict['model.form.linkform'],
+      tooltip: '鍦ㄥ垏鎹㈤�夐」鏃朵細鎶婁俊鎭嚜鍔ㄥ~鍏ュ叧鑱旂殑琛ㄥ崟锛堟枃鏈垨鏁板瓧琛ㄥ崟锛変腑銆�',
       initVal: card.linkSubField || [],
       options: inputfields
     },
     {
+      type: 'text',
+      key: 'tooltip',
+      label: '琛ㄥ崟娉ㄩ噴',
+      tooltip: '榧犳爣鎮诞浜庢彁绀烘枃瀛椾笂鏂规椂锛屾樉绀烘敞閲娿��',
+      initVal: card.tooltip || '',
+      required: false
+    },
+    {
       type: 'multiselect',
       key: 'blacklist',
       label: Formdict['header.form.blacklist'],
diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx
new file mode 100644
index 0000000..3d2c6d0
--- /dev/null
+++ b/src/templates/zshare/modalform/datatable/index.jsx
@@ -0,0 +1,368 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Table, Input, Popconfirm, Form, Icon, notification } from 'antd'
+
+import Utils from '@/utils/utils.js'
+import FileUpload from '@/tabviews/zshare/fileupload'
+import './index.scss'
+
+const EditableContext = React.createContext()
+
+class EditableCell extends Component {
+  getInput = (form) => {
+    const { inputType } = this.props
+    if (inputType === 'file') {
+      return <FileUpload maxFile={1} fileType="picture-card"/>
+    } else {
+      return <Input onPressEnter={() => this.getValue(form)} />
+    }
+  }
+
+  getValue = (form) => {
+    const { record } = this.props
+    form.validateFields((error, row) => {
+      if (error) {
+        return
+      }
+
+      if (row.$url && Array.isArray(row.$url)) {
+        if (!row.$url[0]) {
+          row.$url = ''
+        } else if (row.$url[0].origin) {
+          row.$url = row.$url[0].url || ''
+        } else if (!row.$url[0].origin && row.$url[0].status === 'done' && row.$url[0].response) {
+          row.$url = row.$url[0].response
+        }
+      }
+      this.props.onSave({...record, ...row})
+    })
+  }
+
+  renderCell = (form) => {
+    const { getFieldDecorator } = form
+    const {
+      editing,
+      dataIndex,
+      title,
+      record,
+      inputType,
+      index,
+      children,
+      onSave,
+      ...restProps
+    } = this.props;
+
+    let _val = ''
+
+    if (record && dataIndex) {
+      _val = record[dataIndex]
+    }
+
+    if (dataIndex === '$url' && _val) {
+      _val = [{
+        uid: `10086`,
+        name: _val.slice(_val.lastIndexOf('/') + 1),
+        status: 'done',
+        url: _val,
+        origin: true
+      }]
+    } else if (dataIndex === '$url') {
+      _val = []
+    }
+
+    return (
+      <td {...restProps}>
+        {editing ? (
+          <Form.Item style={{ margin: 0 }}>
+            {getFieldDecorator(dataIndex, {
+              rules: [
+                {
+                  required: dataIndex === '$value',
+                  message: `Please Input ${title}!`,
+                },
+              ],
+              initialValue: _val,
+            })(this.getInput(form))}
+          </Form.Item>
+        ) : (
+          children
+        )}
+      </td>
+    )
+  }
+
+  render() {
+    return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
+  }
+}
+
+class EdiDataTable extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,         // 瀛楀吀椤�
+    type: PropTypes.object,         // 鏁版嵁绫诲瀷锛屾枃鏈�佸浘鐗�
+    fields: PropTypes.array,        // 瀛楁闆�
+    onChange: PropTypes.func        // 鏁版嵁鍙樺寲
+  }
+
+  UNSAFE_componentWillMount () {
+    let data = this.props['data-__meta'].initialValue
+
+    this.setState({
+      data: data,
+      columns: this.getCloumns()
+    })
+  }
+
+  state = {
+    data: [],
+    editingKey: '',
+    columns: []
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.fields), fromJS(nextProps.fields)) || !is(fromJS(this.props.type), fromJS(nextProps.type))) {
+      this.setState({editingKey: ''}, () => {
+        this.setState({
+          columns: this.getCloumns()
+        })
+      })
+    }
+  }
+
+  getCloumns = () => {
+    const { type, fields } = this.props
+    let columns = []
+
+    if (type === 'picture') {
+      columns.push({
+        title: 'url',
+        dataIndex: '$url',
+        inputType: 'file',
+        width: '40%',
+        editable: true,
+        render: (text) => {
+          if (!text) return ''
+          return <span style={{display: 'block', width: '70px', height: '70px'}}><img style={{width: '100%', height: '100%'}} src={text} alt="" /></span>
+        }
+      })
+    } else {
+      columns = fields.map(item => ({
+        title: item.field,
+        dataIndex: item.field,
+        editable: true,
+      }))
+    }
+    
+    columns.unshift({
+      title: 'Value',
+      dataIndex: '$value',
+      editable: true,
+    })
+
+    columns.push({
+      title: 'operation',
+      dataIndex: 'operation',
+      width: '18%',
+      render: (text, record) => {
+        const { editingKey } = this.state
+        const editable = this.isEditing(record)
+        return editable ? (
+          <span>
+            <EditableContext.Consumer>
+              {form => (
+                <span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}>
+                  淇濆瓨
+                </span>
+              )}
+            </EditableContext.Consumer>
+            <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>鍙栨秷</span>
+          </span>
+        ) : (
+          <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}>
+            <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span>
+            <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span>
+            <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span>
+            {editingKey === '' ? <Popconfirm
+              overlayClassName="popover-confirm"
+              title={this.props.dict['model.query.delete']}
+              onConfirm={() => this.handleDelete(record.key)
+            }>
+              <span className="danger"><Icon type="delete" /></span>
+            </Popconfirm> : null}
+            {editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null}
+          </div>
+        )
+      }
+    })
+    
+    return columns
+  }
+
+  isEditing = record => record.key === this.state.editingKey
+
+  cancel = () => {
+    this.setState({ editingKey: '' })
+  }
+
+  onSave = (record) => {
+    const newData = [...this.state.data]
+    const index = newData.findIndex(item => record.key === item.key)
+    if (index > -1) {
+      newData.splice(index, 1, record)
+      this.setState({ data: newData, editingKey: '' }, () => {
+        this.props.onChange(newData)
+      })
+    }
+  }
+
+  handleDelete = (key) => {
+    const { data } = this.state
+    let _data = data.filter(item => key !== item.key)
+
+    this.setState({
+      data: _data
+    }, () => {
+      this.props.onChange(_data)
+    })
+  }
+
+  handleUpDown = (key, direction) => {
+    let _data = fromJS(this.state.data).toJS()
+    const index = _data.findIndex(item => key === item.key)
+
+    if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) {
+      return
+    }
+
+    if (direction === 'up') {
+      _data.splice(index - 1, 0, ..._data.splice(index, 1))
+    } else {
+      _data.splice(index + 1, 0, ..._data.splice(index, 1))
+    }
+
+    this.setState({
+      data: _data
+    }, () => {
+      this.props.onChange(_data)
+    })
+  }
+
+  save(form, key) {
+    form.validateFields((error, row) => {
+      if (error) {
+        return;
+      }
+
+      if (row.$url && Array.isArray(row.$url)) {
+        if (!row.$url[0]) {
+          row.$url = ''
+        } else if (row.$url[0].origin) {
+          row.$url = row.$url[0].url || ''
+        } else if (!row.$url[0].origin && row.$url[0].status === 'done' && row.$url[0].response) {
+          row.$url = row.$url[0].response
+        }
+      }
+
+      const newData = [...this.state.data]
+      const index = newData.findIndex(item => key === item.key)
+      if (index > -1) {
+        const item = newData[index]
+        newData.splice(index, 1, {
+          ...item,
+          ...row,
+        })
+        this.setState({ data: newData, editingKey: '' }, () => {
+          this.props.onChange(newData)
+        })
+      } else {
+        newData.push(row);
+        this.setState({ data: newData, editingKey: '' }, () => {
+          this.props.onChange(newData)
+        })
+      }
+    })
+  }
+
+  handleAdd = () => {
+    const { fields, type } = this.props
+    if (this.state.editingKey) {
+      notification.warning({
+        top: 92,
+        message: '璇蜂繚瀛樼紪杈戜腑鐨勫厓绱狅紒',
+        duration: 5
+      })
+      return
+    }
+
+    let item = { key: Utils.getuuid(), $value: `${this.state.data.length + 1}` }
+
+    if (type === 'picture') {
+      item.$url = ''
+    } else {
+      fields.forEach(f => {
+        item[f.field] = `${this.state.data.length + 1}`
+      })
+    }
+
+    let data = [...this.state.data, item]
+
+    this.setState({ data }, () => {
+      this.props.onChange(data)
+    })
+  }
+
+  edit(key) {
+    this.setState({ editingKey: key })
+  }
+
+  render() {
+    const components = {
+      body: {
+        cell: EditableCell,
+      },
+    }
+
+    const columns = this.state.columns.map(col => {
+      if (!col.editable) {
+        return col
+      }
+      return {
+        ...col,
+        onCell: record => ({
+          record,
+          dataIndex: col.dataIndex,
+          inputType: col.inputType,
+          title: col.title,
+          editing: this.isEditing(record),
+          onSave: this.onSave,
+        }),
+      }
+    })
+
+    let addable = false
+    if (this.props.type === 'picture') {
+      addable = true
+    } else if (this.props.fields && this.props.fields.length > 0) {
+      addable = true
+    }
+
+    return (
+      <EditableContext.Provider value={this.props.form}>
+        <div className="modal-card-data-table">
+          {addable ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null}
+          <Table
+            components={components}
+            bordered
+            dataSource={this.state.data}
+            columns={columns}
+            rowClassName="editable-row"
+            pagination={false}
+          />
+        </div>
+      </EditableContext.Provider>
+    )
+  }
+}
+
+export default Form.create()(EdiDataTable)
\ No newline at end of file
diff --git a/src/templates/zshare/modalform/datatable/index.scss b/src/templates/zshare/modalform/datatable/index.scss
new file mode 100644
index 0000000..a7441d4
--- /dev/null
+++ b/src/templates/zshare/modalform/datatable/index.scss
@@ -0,0 +1,57 @@
+.modal-card-data-table {
+  .add-row {
+    position: absolute;
+    z-index: 1;
+    right: 10px;
+    top: -30px;
+    padding: 5px;
+    font-size: 18px;
+    color: #26C281;
+  }
+  .editable-row {
+    .ant-form-explain {
+      position: absolute;
+      font-size: 12px;
+      margin-top: -4px;
+    }
+    .ant-form-item-control {
+      line-height: 1;
+    }
+    .fileupload-form-container .ant-upload-list-picture-card .ant-upload-list-item {
+      width: 70px;
+      height: 70px;
+      margin: 0;
+      padding: 2px;
+      .ant-upload-list-item-info > span {
+        height: 100%;
+      }
+    }
+    .fileupload-form-container .ant-upload.ant-upload-select-picture-card {
+      width: 70px;
+      height: 70px;
+    }
+  }
+  .operation-btn {
+    span {
+      margin-right: 7px;
+      cursor: pointer;
+    }
+    .primary {
+      color: #1890ff;
+    }
+    .danger {
+      color: #ff4d4f;
+    }
+  }
+  .operation-btn.disabled {
+    span {
+      cursor: default;
+    }
+    .primary {
+      color: rgba(0, 0, 0, .25);
+    }
+    .danger {
+      color: rgba(0, 0, 0, .25);
+    }
+  }
+}
diff --git a/src/templates/zshare/modalform/fieldtable/index.jsx b/src/templates/zshare/modalform/fieldtable/index.jsx
new file mode 100644
index 0000000..5afa7fd
--- /dev/null
+++ b/src/templates/zshare/modalform/fieldtable/index.jsx
@@ -0,0 +1,308 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
+import { Table, Input, InputNumber, Popconfirm, Form, Icon, notification, Select } from 'antd'
+
+import ColorSketch from '@/mob/colorsketch'
+import Utils from '@/utils/utils.js'
+import './index.scss'
+
+const EditableContext = React.createContext()
+
+class EditableCell extends Component {
+  getInput = (form) => {
+    const { inputType } = this.props
+    if (inputType === 'number') {
+      return <InputNumber min={12} max={50} precision={0} onPressEnter={() => this.getValue(form)} />
+    } else if (inputType === 'color') {
+      return <ColorSketch />
+    } else if (inputType === 'select') {
+      return <Select>
+        <Select.Option key="left" value="left"> left </Select.Option>
+        <Select.Option key="center" value="center"> center </Select.Option>
+        <Select.Option key="right" value="right"> right </Select.Option>
+        <Select.Option key="justify" value="justify"> justify </Select.Option>
+      </Select>
+    } else {
+      return <Input onPressEnter={() => this.getValue(form)} />
+    }
+  }
+
+  getValue = (form) => {
+    const { record } = this.props
+    form.validateFields((error, row) => {
+      if (error) {
+        return
+      }
+      this.props.onSave({...record, ...row})
+    })
+  }
+
+  renderCell = (form) => {
+    const { getFieldDecorator } = form
+    const {
+      editing,
+      dataIndex,
+      title,
+      inputType,
+      record,
+      index,
+      children,
+      onSave,
+      ...restProps
+    } = this.props;
+    return (
+      <td {...restProps}>
+        {editing ? (
+          <Form.Item style={{ margin: 0 }}>
+            {getFieldDecorator(dataIndex, {
+              rules: [
+                {
+                  required: true,
+                  message: `Please Input ${title}!`,
+                },
+              ],
+              initialValue: record[dataIndex],
+            })(this.getInput(form))}
+          </Form.Item>
+        ) : (
+          children
+        )}
+      </td>
+    )
+  }
+
+  render() {
+    return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
+  }
+}
+
+class EdiFieldsTable extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,         // 瀛楀吀椤�
+    onChange: PropTypes.func        // 鏁版嵁鍙樺寲
+  }
+
+  UNSAFE_componentWillMount () {
+    let data = this.props['data-__meta'].initialValue
+
+    this.setState({
+      data: data
+    })
+  }
+
+  state = {
+    data: [],
+    editingKey: '',
+    columns: [
+      {
+        title: '瀛楁鍚�',
+        dataIndex: 'field',
+        inputType: 'input',
+        editable: true,
+      },
+      {
+        title: '瀛椾綋棰滆壊',
+        dataIndex: 'color',
+        inputType: 'color',
+        editable: true,
+        render: (text, record) => {
+          return <span style={{color: text}}>绀轰緥</span>
+        }
+      },
+      {
+        title: '瀛椾綋澶у皬',
+        dataIndex: 'fontSize',
+        inputType: 'number',
+        editable: true,
+      },
+      {
+        title: '瀵归綈鏂瑰紡',
+        dataIndex: 'align',
+        inputType: 'select',
+        editable: true,
+      },
+      {
+        title: 'operation',
+        dataIndex: 'operation',
+        width: '18%',
+        render: (text, record) => {
+          const { editingKey } = this.state
+          const editable = this.isEditing(record)
+          return editable ? (
+            <span>
+              <EditableContext.Consumer>
+                {form => (
+                  <span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}>
+                    淇濆瓨
+                  </span>
+                )}
+              </EditableContext.Consumer>
+              <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>鍙栨秷</span>
+            </span>
+          ) : (
+            <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}>
+              <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span>
+              <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span>
+              <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span>
+              {editingKey === '' ? <Popconfirm
+                overlayClassName="popover-confirm"
+                title={this.props.dict['model.query.delete']}
+                onConfirm={() => this.handleDelete(record.key)
+              }>
+                <span className="danger"><Icon type="delete" /></span>
+              </Popconfirm> : null}
+              {editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null}
+            </div>
+          )
+        },
+      },
+    ]
+  }
+
+  isEditing = record => record.key === this.state.editingKey
+
+  cancel = () => {
+    this.setState({ editingKey: '' })
+  }
+
+  onSave = (record) => {
+    const newData = [...this.state.data]
+    const index = newData.findIndex(item => record.key === item.key)
+    if (index > -1) {
+      newData.splice(index, 1, record)
+      this.setState({ data: newData, editingKey: '' }, () => {
+        this.props.onChange(newData)
+      })
+    }
+  }
+
+  handleDelete = (key) => {
+    const { data } = this.state
+    let _data = data.filter(item => key !== item.key)
+
+    this.setState({
+      data: _data
+    }, () => {
+      this.props.onChange(_data)
+    })
+  }
+
+  handleUpDown = (key, direction) => {
+    let _data = fromJS(this.state.data).toJS()
+    const index = _data.findIndex(item => key === item.key)
+
+    if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) {
+      return
+    }
+
+    if (direction === 'up') {
+      _data.splice(index - 1, 0, ..._data.splice(index, 1))
+    } else {
+      _data.splice(index + 1, 0, ..._data.splice(index, 1))
+    }
+
+    this.setState({
+      data: _data
+    }, () => {
+      this.props.onChange(_data)
+    })
+  }
+
+  save(form, key) {
+    form.validateFields((error, row) => {
+      if (error) {
+        return;
+      }
+      const newData = [...this.state.data]
+      const index = newData.findIndex(item => key === item.key)
+      if (index > -1) {
+        const item = newData[index]
+        newData.splice(index, 1, {
+          ...item,
+          ...row,
+        })
+        this.setState({ data: newData, editingKey: '' }, () => {
+          this.props.onChange(newData)
+        })
+      } else {
+        newData.push(row);
+        this.setState({ data: newData, editingKey: '' }, () => {
+          this.props.onChange(newData)
+        })
+      }
+    })
+  }
+
+  handleAdd = () => {
+    if (this.state.editingKey) {
+      notification.warning({
+        top: 92,
+        message: '璇蜂繚瀛樼紪杈戜腑鐨勫厓绱狅紒',
+        duration: 5
+      })
+      return
+    }
+
+    let item = {
+      key: Utils.getuuid(),
+      field: `field${this.state.data.length + 1}`,
+      color: 'rgba(0, 0, 0, 0.85)',
+      align: 'left',
+      fontSize: 14,
+    }
+
+    let data = [...this.state.data, item]
+
+    this.setState({ data }, () => {
+      this.props.onChange(data)
+    })
+  }
+
+  edit(key) {
+    this.setState({ editingKey: key })
+  }
+
+  render() {
+    const components = {
+      body: {
+        cell: EditableCell,
+      },
+    }
+
+    const columns = this.state.columns.map(col => {
+      if (!col.editable) {
+        return col
+      }
+      return {
+        ...col,
+        onCell: record => ({
+          record,
+          inputType: col.inputType,
+          dataIndex: col.dataIndex,
+          title: col.title,
+          editing: this.isEditing(record),
+          onSave: this.onSave,
+        }),
+      }
+    })
+
+    return (
+      <EditableContext.Provider value={this.props.form}>
+        <div className="modal-card-data-table">
+          {this.state.data.length < 3 ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null}
+          <Table
+            components={components}
+            bordered
+            dataSource={this.state.data}
+            columns={columns}
+            rowClassName="editable-row"
+            pagination={false}
+          />
+        </div>
+      </EditableContext.Provider>
+    )
+  }
+}
+
+export default Form.create()(EdiFieldsTable)
\ No newline at end of file
diff --git a/src/templates/zshare/modalform/fieldtable/index.scss b/src/templates/zshare/modalform/fieldtable/index.scss
new file mode 100644
index 0000000..8d7be74
--- /dev/null
+++ b/src/templates/zshare/modalform/fieldtable/index.scss
@@ -0,0 +1,52 @@
+.modal-card-data-table {
+  .add-row {
+    position: absolute;
+    z-index: 1;
+    right: 10px;
+    top: -30px;
+    padding: 5px;
+    font-size: 18px;
+    color: #26C281;
+  }
+  .editable-row {
+    .ant-form-explain {
+      position: absolute;
+      font-size: 12px;
+      margin-top: -4px;
+    }
+    .color-sketch-block {
+      width: 200px;
+      position: relative;
+      top: 2px;
+    }
+    .ant-select {
+      width: 80px;
+    }
+  }
+  .operation-btn {
+    span {
+      margin-right: 10px;
+      cursor: pointer;
+    }
+    .primary {
+      color: #1890ff;
+    }
+    .danger {
+      color: #ff4d4f;
+    }
+  }
+  .operation-btn.disabled {
+    span {
+      cursor: default;
+    }
+    .primary {
+      color: rgba(0, 0, 0, .25);
+    }
+    .danger {
+      color: rgba(0, 0, 0, .25);
+    }
+  }
+  .ant-empty {
+    margin: 0;
+  }
+}
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index 689c1f2..d77c06d 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -6,27 +6,32 @@
 import { dateOptions } from '@/utils/option.js'
 import Utils from '@/utils/utils.js'
 import EditTable from './modaleditable'
+import DataTable from './datatable'
+import FieldsTable from './fieldtable'
 import CodeMirror from '@/templates/zshare/codemirror'
 import './index.scss'
 
+const { TextArea } = Input
+
 const modalTypeOptions = {
-  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine'],
-  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine'],
-  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine'],
-  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'],
-  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'],
-  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'display'],
-  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine'],
-  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine'],
-  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine'],
-  switch: ['initval', 'openVal', 'closeVal', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
-  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
-  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
-  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
-  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception'],
-  color: ['readonly', 'required', 'hidden', 'readin', 'entireLine'],
-  funcvar: ['hidden'],
-  linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine']
+  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine', 'tooltip'],
+  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine', 'tooltip'],
+  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine', 'tooltip'],
+  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'entireLine', 'tooltip'],
+  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine', 'tooltip'],
+  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'display', 'tooltip', 'width', 'multiple'],
+  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine', 'tooltip'],
+  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine', 'tooltip'],
+  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine', 'tooltip'],
+  switch: ['initval', 'openVal', 'closeVal', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
+  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
+  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
+  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
+  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception', 'tooltip'],
+  color: ['readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
+  hint: ['label', 'type', 'blacklist', 'message'],
+  funcvar: [],
+  linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine', 'tooltip']
 }
 
 class MainSearch extends Component {
@@ -41,6 +46,8 @@
     openType: null,
     resourceType: null,
     supField: '',
+    display: 'text',
+    cFields: [],
     formlist: null,
     linkSubFields: null
   }
@@ -51,11 +58,17 @@
     let type = ''
     let resourceType = ''
     let supField = ''
+    let display = ''
+    let cFields = []
     let linkSubFields = []
 
     formlist.forEach(cell => {
       if (cell.key === 'type') {
         type = cell.initVal
+      } else if (cell.key === 'display') {
+        display = cell.initVal
+      } else if (cell.key === 'fields') {
+        cFields = cell.initVal
       } else if (cell.key === 'resourceType') {
         resourceType = cell.initVal
       } else if (cell.key === 'linkSubField') {
@@ -73,11 +86,13 @@
       }
     })
     
-    let _options = this.getOptions(type, resourceType, supField)
+    let _options = this.getOptions(type, resourceType, supField, display)
 
     this.setState({
       openType: type,
       supField: supField,
+      display: display,
+      cFields: cFields,
       resourceType: resourceType,
       linkSubFields: linkSubFields,
       formlist: formlist.map(form => {
@@ -95,6 +110,11 @@
           form.type = 'number'
           form.initVal = form.initVal || 0
           form.required = true
+        } else if (form.key === 'label') {
+          form.required = true
+          if (type === 'hint') {
+            form.required = false
+          }
         }
 
         form.show = _options.includes(form.key)
@@ -116,14 +136,30 @@
     }
   }
 
-  getOptions = (type, resourceType, supField) => {
+  getOptions = (type, resourceType, supField, display) => {
     let _options = ['label', 'field', 'type', 'blacklist', 'writein', ...fromJS(modalTypeOptions[type]).toJS()]
 
-    if (['multiselect', 'select', 'link', 'radio', 'checkbox', 'checkcard'].includes(type)) {
+    if (type === 'hint') {
+      _options = fromJS(modalTypeOptions[type]).toJS()
+    } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(type)) {
       if (resourceType === '0') {        // 鑷畾涔夎祫婧�
-        _options = [..._options, 'options']
+        _options.push('options')
       } else if (resourceType === '1') { // 鏁版嵁婧�
-        _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database']
+        _options.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database')
+      }
+    } else if (type === 'checkcard') {
+      if (display === 'picture') {
+        if (resourceType === '0') {        // 鑷畾涔夎祫婧�
+          _options.push('options', 'ratio')
+        } else if (resourceType === '1') { // 鏁版嵁婧�
+          _options.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'database', 'ratio')
+        }
+      } else {
+        if (resourceType === '0') {        // 鑷畾涔夎祫婧�
+          _options.push('options', 'fields')
+        } else if (resourceType === '1') { // 鏁版嵁婧�
+          _options.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database')
+        }
       }
     }
 
@@ -140,7 +176,7 @@
 
   openTypeChange = (key, value) => {
     if (key === 'type') {
-      let _options = this.getOptions(value, this.state.resourceType, this.state.supField)
+      let _options = this.getOptions(value, this.state.resourceType, this.state.supField, this.state.display)
       let fieldValue = {}
       
       this.setState({
@@ -192,7 +228,13 @@
             if (form.show) {
               fieldValue.linkSubField = form.initVal
             }
+          } else if (form.key === 'label') {
+            form.required = true
+            if (value === 'hint') {
+              form.required = false
+            }
           }
+
           return form
         })
       }, () => {
@@ -240,7 +282,7 @@
     const { openType } = this.state
     let value = e.target.value
     if (key === 'resourceType') {
-      let _options = this.getOptions(openType, value, this.state.supField)
+      let _options = this.getOptions(openType, value, this.state.supField, this.state.display)
       
       this.setState({
         resourceType: value,
@@ -249,7 +291,27 @@
           return form
         })
       })
+    } else if (key === 'display') {
+      let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, value)
+      
+      this.setState({
+        display: value,
+        formlist: this.state.formlist.map(form => {
+          form.show = _options.includes(form.key)
+          return form
+        })
+      })
+    } else if (key === 'multiple') {
+      if (value === 'true') {
+        this.props.form.setFieldsValue({fieldlength: 512})
+      } else {
+        this.props.form.setFieldsValue({fieldlength: 50})
+      }
     }
+  }
+
+  changeField = (data) => {
+    this.setState({cFields: data})
   }
 
   handleSubmit = (e) => {
@@ -262,6 +324,7 @@
 
   getFields() {
     const { getFieldDecorator } = this.props.form
+    const { openType } = this.state
     const fields = []
 
     this.state.formlist.forEach((item, index) => {
@@ -355,6 +418,27 @@
               </Form.Item>
             </Col>
           )
+        } else if (item.key === 'width') {
+          fields.push(
+            <Col span={12} key={index}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title={item.tooltip}>
+                  <Icon type="question-circle" />
+                  {item.label}
+                </Tooltip>
+              }>
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal,
+                  rules: [
+                    {
+                      required: !!item.required,
+                      message: this.props.dict['form.required.input'] + item.label + '!'
+                    }
+                  ]
+                })(<InputNumber min={1} max={24} precision={0} />)}
+              </Form.Item>
+            </Col>
+          )
         } else {
           fields.push(
             <Col span={12} key={index}>
@@ -409,7 +493,12 @@
       } else if (item.type === 'multiselect') { // 澶氶��
         fields.push(
           <Col span={12} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
               {getFieldDecorator(item.key, {
                 initialValue: item.initVal
               })(
@@ -458,10 +547,10 @@
             </Form.Item>
           </Col>
         )
-      } else if (item.type === 'textarea') {
+      } else if (item.type === 'codemirror') {
         fields.push(
-          <Col span={20} offset={4} key={index}>
-            <Form.Item className="text-area">
+          <Col span={24} key={index}>
+            <Form.Item className="text-area" label={item.label}>
               {getFieldDecorator(item.key, {
                 initialValue: item.initVal,
                 rules: [
@@ -474,15 +563,52 @@
             </Form.Item>
           </Col>
         )
-      } else if (item.type === 'options') {
+      } else if (item.type === 'textarea') {
         fields.push(
-          <Col span={20} offset={4} key={index}>
-            <Form.Item className="text-area">
+          <Col span={24} key={index}>
+            <Form.Item className="text-msg" label={item.label}>
+              {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') {
+        if (openType !== 'checkcard') {
+          fields.push(
+            <Col span={24} key={index}>
+              <Form.Item label={item.label} className="text-area">
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal
+                })(<EditTable dict={this.props.dict} type={openType} linkSubFields={this.state.linkSubFields}/>)}
+              </Form.Item>
+            </Col>
+          )
+        } else {
+          fields.push(
+            <Col span={24} key={index}>
+              <Form.Item label={item.label} className="text-area">
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal
+                })(<DataTable dict={this.props.dict} type={this.state.display} fields={this.state.cFields}/>)}
+              </Form.Item>
+            </Col>
+          )
+        }
+      } else if (item.type === 'fields') {
+        fields.push(
+          <Col span={24} key={index}>
+            <Form.Item label={item.label} className="text-area">
               {getFieldDecorator(item.key, {
                 initialValue: item.initVal
-              })(<EditTable dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields}/>)}
+              })(<FieldsTable dict={this.props.dict} onChange={this.changeField}/>)}
             </Form.Item>
-            {/* <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> */}
           </Col>
         )
       }
@@ -575,7 +701,7 @@
       }
     }
     return (
-      <Form {...formItemLayout} className="ant-advanced-search-form modal-fields-form" id="modal-fields-form-box">
+      <Form {...formItemLayout} className="modal-fields-form" id="modal-fields-form-box">
         <Row gutter={24}>{this.getFields()}</Row>
       </Form>
     )
diff --git a/src/templates/zshare/modalform/index.scss b/src/templates/zshare/modalform/index.scss
index 1b27f24..fe098e2 100644
--- a/src/templates/zshare/modalform/index.scss
+++ b/src/templates/zshare/modalform/index.scss
@@ -1,22 +1,38 @@
-.ant-advanced-search-form.modal-fields-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-form-item-control-wrapper {
+      width: 84%;
+      .ant-table-tbody > tr > td {
+        padding: 16px 10px;
+      }
+    }
+    >.ant-form-item-label {
+      width: 16%;
     }
     .CodeMirror {
       height: 150px;
     }
   }
+  .ant-form-item.text-msg {
+    >.ant-form-item-label {
+      width: 16%;
+    }
+    >.ant-form-item-control-wrapper {
+      width: 84%;
+    }
+  }
   .ant-form-item-label .anticon-question-circle {
     color: #c49f47;
     margin-right: 3px;
   }
+  .ant-radio-group {
+    white-space: nowrap;
+  }
   .ant-input-number {
     width: 100%;
   }
diff --git a/src/templates/zshare/modalform/modaleditable/index.jsx b/src/templates/zshare/modalform/modaleditable/index.jsx
index f24e275..9b5f7d7 100644
--- a/src/templates/zshare/modalform/modaleditable/index.jsx
+++ b/src/templates/zshare/modalform/modaleditable/index.jsx
@@ -131,39 +131,30 @@
       data = []
     }
 
-    let _width = '40%'
     let fields = []
     let dataItem = data[0] || ''
 
-    if (type === 'link') {
-      _width = '27%'
-    } else if (type === 'select') {
-      _width = Math.floor(80 / (linkSubFields.length + 2)) + '%'
+    if (type === 'select' || type === 'radio') {
       fields = linkSubFields.map(cell => {
         return {
           title: cell.label,
           dataIndex: cell.field,
-          width: _width,
           editable: true,
           datatype: dataItem && typeof(dataItem[cell.field]) === 'number' ? 'number' : 'string'
         }
       })
     }
 
-    
-
     let columns = [
       {
         title: 'Value',
         dataIndex: 'Value',
-        width: _width,
         editable: true,
         datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
       },
       {
         title: 'Text',
         dataIndex: 'Text',
-        width: _width,
         editable: true,
         datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
       },
@@ -171,6 +162,7 @@
       {
         title: '鎿嶄綔',
         align: 'center',
+        width: '20%',
         dataIndex: 'operation',
         render: (text, record) =>
           this.state.dataSource.length >= 1 ? (
@@ -193,7 +185,6 @@
       columns.unshift({
         title: 'ParentID',
         dataIndex: 'ParentID',
-        width: '27%',
         editable: true,
         datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
       })
@@ -345,10 +336,9 @@
 
   resetColumn = (type, linkSubFields) => {
     let dataSource = JSON.parse(JSON.stringify(this.state.dataSource))
-    let _width = '40%'
     let fields = []
 
-    if (type === 'select' && linkSubFields.length > this.state.linkSubFields) {
+    if ((type === 'select' || type === 'radio') && linkSubFields.length > this.state.linkSubFields) {
       let addcol = linkSubFields[linkSubFields.length - 1]
       dataSource = dataSource.map(data => {
         data[addcol.field] = data.Text
@@ -358,15 +348,11 @@
 
     let dataItem = dataSource ? dataSource[0] : ''
 
-    if (type === 'link') {
-      _width = '27%'
-    } else if (type === 'select') {
-      _width = Math.floor(80 / (linkSubFields.length + 2)) + '%'
+    if (type === 'select' || type === 'radio') {
       fields = linkSubFields.map(field => {
         return {
           title: field.label,
           dataIndex: field.field,
-          width: _width,
           editable: true,
           datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
         }
@@ -377,14 +363,12 @@
       {
         title: 'Value',
         dataIndex: 'Value',
-        width: _width,
         editable: true,
         datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
       },
       {
         title: 'Text',
         dataIndex: 'Text',
-        width: _width,
         editable: true,
         datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
       },
@@ -392,6 +376,7 @@
       {
         title: '鎿嶄綔',
         align: 'center',
+        width: '20%',
         dataIndex: 'operation',
         render: (text, record) =>
           this.state.dataSource.length >= 1 ? (
@@ -414,7 +399,6 @@
       columns.unshift({
         title: 'ParentID',
         dataIndex: 'ParentID',
-        width: '27%',
         editable: true,
         datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
       })
diff --git a/src/templates/zshare/modalform/modaleditable/index.scss b/src/templates/zshare/modalform/modaleditable/index.scss
index 439a1c8..7400628 100644
--- a/src/templates/zshare/modalform/modaleditable/index.scss
+++ b/src/templates/zshare/modalform/modaleditable/index.scss
@@ -2,7 +2,7 @@
   .add-row {
     position: absolute;
     z-index: 1;
-    right: 20px;
+    right: 10px;
     top: -30px;
     padding: 5px;
     font-size: 18px;
@@ -40,4 +40,9 @@
     margin-right: 10px;
     cursor: pointer;
   }
+  .ant-form-explain {
+    .editable-row {
+      font-size: 12px;
+    }
+  }
 }

--
Gitblit v1.8.0