From ddddb07002201150da9551875c25e75499563249 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 15 一月 2021 15:22:55 +0800
Subject: [PATCH] 2021-01-15

---
 src/menu/components/share/usercomponent/settingform/index.jsx |    4 
 src/menu/components/share/usercomponent/index.jsx             |  184 ++++++++++++++----
 src/mob/header/index.jsx                                      |    4 
 src/templates/zshare/editTable/index.jsx                      |    7 
 src/components/header/index.jsx                               |    3 
 src/menu/components/card/table-card/index.jsx                 |   59 +++--
 src/menu/components/card/data-card/index.jsx                  |   20 -
 src/menu/components/chart/antv-pie/index.jsx                  |   19 +
 src/menu/components/chart/antv-bar/index.jsx                  |   46 +++-
 src/menu/modelsource/option.jsx                               |   14 
 src/menu/components/card/prop-card/index.jsx                  |   20 -
 src/menu/components/table/normal-table/index.jsx              |   58 +++++
 src/menu/modelsource/dragsource/index.jsx                     |    9 
 src/menu/header/index.jsx                                     |    4 
 src/menu/modelsource/index.jsx                                |   52 +++++
 src/menu/modelsource/dragsource/index.scss                    |   15 +
 src/views/menudesign/index.jsx                                |    1 
 src/assets/css/main.scss                                      |   26 ++
 18 files changed, 416 insertions(+), 129 deletions(-)

diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 7031e4b..400975a 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -256,7 +256,31 @@
 }
 
 .ant-modal.popview-modal {
-  top: 80px;
+  top: 70px;
+  .ant-modal-body {
+    min-height: 250px;
+    max-height: calc(100vh - 210px);
+    overflow-y: auto;
+  }
+  .ant-modal-body::-webkit-scrollbar {
+    width: 7px;
+  }
+  .ant-modal-body::-webkit-scrollbar-thumb {
+    border-radius: 5px;
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+    background: rgba(0, 0, 0, 0.13);
+  }
+  .ant-modal-body::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+    border-radius: 3px;
+    border: 1px solid rgba(0, 0, 0, 0.07);
+    background: rgba(0, 0, 0, 0);
+  }
+}
+.ant-modal-wrap.popview-modal {
+  .ant-modal {
+    top: 70px;
+  }
   .ant-modal-body {
     min-height: 250px;
     max-height: calc(100vh - 210px);
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 2b2bf02..5d9c7b7 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -25,6 +25,7 @@
 import enUS from '@/locales/en-US/main.js'
 import Utils from '@/utils/utils.js'
 import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
 import Resetpwd from './resetpwd'
 import LoginForm from './loginform'
 import './index.scss'
@@ -746,7 +747,7 @@
 
     return (
       <header className="header-container ant-menu-dark" id="main-header-container">
-        <div className={'header-logo ' + (collapse ? 'collapse' : '')}><img src={this.state.logourl} alt=""/></div>
+        <div className={'header-logo ' + (collapse ? 'collapse' : '')}><img src={!this.props.editState ? this.state.logourl : MainLogo} alt=""/></div>
         <div className={'header-collapse ' + (collapse ? 'collapse' : '')}>
           {menulist && menulist.length ? <Icon type={collapse ? 'menu-unfold' : 'menu-fold'} onClick={this.handleCollapse}/> : null}
         </div>
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 5ced615..37cebdb 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -52,16 +52,17 @@
         pageable: true,    // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
         switchable: true,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
         dataName: card.dataName || '',
-        width: 24,
+        width: card.width || 24,
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: 24, title: '', pagestyle: 'page', switch: 'false' },
+        wrap: { name: card.name, width: card.width || 24, title: '', pagestyle: 'page', switch: 'false' },
         style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
         headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
         columns: [],
         scripts: [],
         action: [],
+        search: [],
         btnlog: [],
         subcards: [{
           uuid: Utils.getuuid(),
@@ -80,8 +81,8 @@
       if (card.config) {
         let config = fromJS(card.config).toJS()
 
-        _card.setting = config.setting
         _card.wrap = config.wrap
+        _card.wrap.name = card.name
         _card.style = config.style
         _card.headerStyle = config.headerStyle
 
@@ -97,15 +98,11 @@
           })
           return scard
         })
-        _card.columns = config.columns.map(col => {
-          col.uuid = Utils.getuuid()
-          return col
-        })
-        _card.scripts = config.scripts.map(col => {
-          col.uuid = Utils.getuuid()
-          return col
-        })
         _card.action = config.action.map(col => {
+          col.uuid = Utils.getuuid()
+          return col
+        })
+        _card.search = config.search.map(col => {
           col.uuid = Utils.getuuid()
           return col
         })
@@ -118,6 +115,7 @@
     } else {
       card.action = card.action || [] // 鍏煎
       card.search = card.search || [] // 鍏煎
+
       this.setState({
         card: fromJS(card).toJS()
       })
diff --git a/src/menu/components/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index 9b0e60f..9032026 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -51,11 +51,11 @@
         pageable: false,    // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
         switchable: true,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
         dataName: card.dataName || '',
-        width: 24,
+        width: card.width || 24,
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: 24, title: '', addable: 'false', switch: 'false', datatype: 'static' },
+        wrap: { name: card.name, width: card.width || 24, title: '', addable: 'false', switch: 'false', datatype: 'static' },
         style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
         headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
         columns: [],
@@ -78,8 +78,8 @@
       if (card.config) {
         let config = fromJS(card.config).toJS()
 
-        _card.setting = config.setting
         _card.wrap = config.wrap
+        _card.wrap.name = card.name
         _card.style = config.style
         _card.headerStyle = config.headerStyle
 
@@ -94,14 +94,6 @@
             return elem
           })
           return scard
-        })
-        _card.columns = config.columns.map(col => {
-          col.uuid = Utils.getuuid()
-          return col
-        })
-        _card.scripts = config.scripts.map(col => {
-          col.uuid = Utils.getuuid()
-          return col
         })
       }
       this.setState({
@@ -309,8 +301,10 @@
 
       card.btnlog = logs
 
-      this.setState({ card })
-      this.props.updateConfig(card)
+      this.setState({ card: {...card, subcards: []} }, () => {
+        this.setState({ card })
+        this.props.updateConfig(card)
+      })
       if (!done) {
         notification.warning({
           top: 92,
diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index efc6e15..b84b815 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -19,6 +19,7 @@
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 
 const { confirm } = Modal
@@ -40,29 +41,6 @@
     const { card } = this.props
 
     if (card.isNew) {
-      let subcards = null
-
-      if (card.config) {
-        subcards = JSON.parse(card.config)
-        subcards = subcards.map(scard => {
-          scard.uuid = Utils.getuuid()
-          scard.elements = scard.elements.map(elem => {
-            elem.uuid = Utils.getuuid()
-            return elem
-          })
-          return scard
-        })
-      } else {
-        subcards = [{
-          uuid: Utils.getuuid(),
-          setting: { width: 24, type: 'simple'},
-          style: {
-            paddingTop: '5px', paddingBottom: '5px', paddingLeft: '15px', paddingRight: '15px',
-          },
-          elements: []
-        }]
-      }
-
       let _card = {
         uuid: card.uuid,
         type: card.type,
@@ -73,20 +51,48 @@
         pageable: true,     // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
         switchable: false,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
         dataName: card.dataName || '',
-        width: 12,
+        width: card.width || 12,
         search: [],
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: 12, title: '' },
+        wrap: { name: card.name, width: card.width || 12, title: '' },
         style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
         headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
         columns: [],
         scripts: [],
-        subcards: subcards,
+        subcards: [{
+          uuid: Utils.getuuid(),
+          setting: { width: 24, type: 'simple'},
+          style: {
+            paddingTop: '5px', paddingBottom: '5px', paddingLeft: '15px', paddingRight: '15px',
+          },
+          elements: []
+        }],
         btnlog: [],
       }
       
+      if (card.config) {
+        let config = fromJS(card.config).toJS()
+
+        _card.wrap = config.wrap
+        _card.wrap.name = card.name
+        _card.style = config.style
+        _card.headerStyle = config.headerStyle
+
+        _card.subcards = config.subcards.map(scard => {
+          scard.uuid = Utils.getuuid()
+          scard.elements = scard.elements.map(elem => {
+            elem.uuid = Utils.getuuid()
+            return elem
+          })
+          return scard
+        })
+        _card.search = config.search.map(col => {
+          col.uuid = Utils.getuuid()
+          return col
+        })
+      }
       this.setState({
         card: _card
       })
@@ -331,6 +337,7 @@
             <PasteComponent config={card} options={['cardcell', 'search', 'form']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            <UserComponent config={card}/>
             <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
             {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
           </div>
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index c2ee506..25074e0 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -23,6 +23,7 @@
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
+const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 
 class antvBarLineChart extends Component {
   static propTpyes = {
@@ -46,7 +47,7 @@
         enabled: 'false',     // 鏄惁浣跨敤鑷畾涔夎缃�
         datatype: 'query',    // 鏁版嵁绫诲瀷鏌ヨ鎴栫粺璁�
         customs: [],
-        width: 24,
+        width: card.width || 24,
         height: 400,
         barSize: 35,
         name: card.name
@@ -89,6 +90,24 @@
         action: [],
         plot: _plot,
         btnlog: [],
+      }
+
+      if (card.config) {
+        let config = fromJS(card.config).toJS()
+
+        _card.plot = config.plot
+        _card.plot.name = card.name
+        _card.style = config.style
+        _card.headerStyle = config.headerStyle
+
+        _card.action = config.action.map(col => {
+          col.uuid = Utils.getuuid()
+          return col
+        })
+        _card.search = config.search.map(col => {
+          col.uuid = Utils.getuuid()
+          return col
+        })
       }
       this.setState({
         card: _card
@@ -202,7 +221,7 @@
         dv.transform({
           type: 'map',
           callback(row) {
-            row.key = transfield[row.key]
+            row.key = transfield[row.key] || row.key
             return row
           },
         })
@@ -272,12 +291,12 @@
         .line()
         .position(`${X_axis}*value`)
         .shape(plot.shape || 'smooth')
-        .tooltip(`${X_axis}*value`, (name, value) => {
+        .tooltip(`${X_axis}*value*key`, (name, value, type) => {
           if (plot.show === 'percent') {
             value = value + '%'
           }
           return {
-            name: name,
+            name: type,
             value: value
           }
         })
@@ -460,12 +479,12 @@
           .position(`${plot.Xaxis}*${item.name}`)
           .color(item.color)
           .shape(item.shape)
-          .tooltip(`${plot.Xaxis}*${item.name}`, (name, value) => {
+          .tooltip(`${item.name}`, (value) => {
             if (plot.show === 'percent') {
               value = value + '%'
             }
             return {
-              name: name,
+              name: item.name,
               value: value
             }
           })
@@ -492,12 +511,12 @@
           .position(`${plot.Xaxis}*${item.name}`)
           .color(item.color)
           .shape(item.shape)
-          .tooltip(`${plot.Xaxis}*${item.name}`, (name, value) => {
+          .tooltip(`${item.name}`, (value) => {
             if (plot.show === 'percent') {
               value = value + '%'
             }
             return {
-              name: name,
+              name: item.name,
               value: value
             }
           })
@@ -564,7 +583,7 @@
         dv.transform({
           type: 'map',
           callback(row) {
-            row.key = transfield[row.key]
+            row.key = transfield[row.key] || row.key
             return row
           },
         })
@@ -636,12 +655,12 @@
             }
           ])
           .shape(plot.shape || 'rect')
-          .tooltip(`${X_axis}*value`, (name, value) => {
+          .tooltip(`${X_axis}*value*key`, (name, value, key) => {
             if (plot.show === 'percent') {
               value = value + '%'
             }
             return {
-              name: name,
+              name: key,
               value: value
             }
           })
@@ -682,12 +701,12 @@
           .position(`${X_axis}*value`)
           .adjust('stack')
           .shape(plot.shape || 'rect')
-          .tooltip(`${X_axis}*value`, (name, value) => {
+          .tooltip(`${X_axis}*value*key`, (name, value, type) => {
             if (plot.show === 'percent') {
               value = value + '%'
             }
             return {
-              name: name,
+              name: type,
               value: value
             }
           })
@@ -875,6 +894,7 @@
             <PasteComponent config={card} options={['action', 'search', 'form']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            <UserComponent config={card}/>
             <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent}/>
           </div>
diff --git a/src/menu/components/chart/antv-pie/index.jsx b/src/menu/components/chart/antv-pie/index.jsx
index c17b950..4745360 100644
--- a/src/menu/components/chart/antv-pie/index.jsx
+++ b/src/menu/components/chart/antv-pie/index.jsx
@@ -21,6 +21,7 @@
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
+const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 
 class antvBarLineChart extends Component {
   static propTpyes = {
@@ -41,7 +42,7 @@
     if (card.isNew) {
       let _plot = {
         shape: card.subtype, // 鍥捐〃绫诲瀷
-        width: 12,
+        width: card.width || 12,
         height: 400,
         label: 'outer',
         name: card.name
@@ -77,6 +78,21 @@
         plot: _plot,
         btnlog: [],
       }
+
+      if (card.config) {
+        let config = fromJS(card.config).toJS()
+
+        _card.plot = config.plot
+        _card.plot.name = card.name
+        _card.style = config.style
+        _card.headerStyle = config.headerStyle
+
+        _card.search = config.search.map(col => {
+          col.uuid = Utils.getuuid()
+          return col
+        })
+      }
+
       this.props.updateConfig(_card)
       this.setState({
         card: _card
@@ -441,6 +457,7 @@
             <PasteComponent config={card} options={['search', 'form']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            <UserComponent config={card}/>
             <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent}/>
           </div>
diff --git a/src/menu/components/share/usercomponent/index.jsx b/src/menu/components/share/usercomponent/index.jsx
index 8936f77..fd071da 100644
--- a/src/menu/components/share/usercomponent/index.jsx
+++ b/src/menu/components/share/usercomponent/index.jsx
@@ -22,7 +22,7 @@
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     visible: false,
     loading: false,
-    name: ''
+    name: '',
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -31,7 +31,7 @@
 
   trigger = () => {
     const { config } = this.props
-    
+
     this.setState({
       visible: true,
       loading: false,
@@ -39,53 +39,151 @@
     })
   }
 
+  getUserComponent = () => {
+    let config = fromJS(this.props.config).toJS()
+    let _config = {}
+
+    _config.wrap = config.wrap || {}
+    _config.type = config.type || ''
+    _config.subtype = config.subtype || ''
+    _config.style = config.style || {}
+    _config.subcards = config.subcards || []
+    _config.headerStyle = config.headerStyle || {}
+    _config.action = config.action || []
+    _config.search = config.search || []
+    _config.cols = config.cols || []
+    _config.plot = config.plot || {}
+
+    _config.width = _config.wrap.width || _config.plot.width || config.width || 24
+
+    _config.subcards = _config.subcards.map(card => {
+      if (card.elements) {
+        card.elements = card.elements.map(item => this.resetElement(item))
+      }
+      if (card.backElements) {
+        card.backElements = card.backElements.map(item => this.resetElement(item))
+      }
+      return card
+    })
+    _config.action = _config.action.map(item => {
+      item.verify = null
+      return item
+    })
+    _config.search = _config.search.map(item => {
+      if (item.resourceType === '1') {
+        item.resourceType = '0'
+        item.dataSource = ''
+        item.valueText = ''
+        item.valueText = ''
+        item.options = ''
+      }
+      item.blacklist = []
+      return item
+    })
+
+    _config.cols = _config.cols.map(col => {
+      if (col.type === 'colspan' && col.subcols) {
+        col = this.loopCol(col)
+      } else if (col.type === 'custom' && col.elements) {
+        col.elements = col.elements.map(cell => this.resetElement(cell))
+      } else if (col.type === 'action' && col.elements) {
+        col.elements = col.elements.map(cell => {
+          cell.verify = null
+          return cell
+        })
+      }
+      col.marks = null
+      return col
+    })
+
+    return _config
+  }
+
+  loopCol = (col) => {
+    col.subcols = col.subcols.map(c => {
+      if (c.type === 'colspan' && c.subcols) {
+        c = this.loopCol(c)
+      } else if (c.type === 'custom' && c.elements) {
+        c.elements = c.elements.map(cell => this.resetElement(cell))
+      }
+      c.marks = null
+      return c
+    })
+
+    return col
+  }
+
+  resetElement = (item) => {
+    item.marks = null
+    item.verify = null
+
+    if (item.datatype === 'dynamic') {
+      if (item.eleType ===  'icon') {
+        item.tooltip = item.field
+      } else if (item.eleType === 'slider') {
+        item.value = 50
+      } else {
+        item.value = item.field
+      }
+      
+      item.datatype = 'static'
+      item.field = ''
+    }
+    if (item.link === 'dynamic') {
+      item.link = 'static'
+    }
+    return item
+  }
+
   submit = () => {
     const { config } = this.props
 
     this.verifyRef.handleConfirm().then(res => {
-      this.setState({loading: true})
       document.getElementsByClassName('menu-view')[0].classList.add('saving')
-
-      html2canvas(document.getElementById(config.uuid)).then(canvas => {
-        let img = canvas.toDataURL('image/png') // 鑾峰彇鐢熸垚鐨勫浘鐗�
-        Api.fileuploadbase64(img, 'cloud').then(result => {
-          if (result.status) {
-            Api.getSystemConfig({
-              func: 's_custom_components_adduptdel',
-              c_id: config.uuid,
-              images: Utils.getcloudurl(result.Images),
-              c_name: res.name,
-              long_param: window.btoa(window.encodeURIComponent(JSON.stringify(config))),
-              del_type: ''
-            }).then(response => {
-              if (response.status) {
-                this.setState({loading: false, visible: false})
-                notification.success({
-                  top: 92,
-                  message: '淇濆瓨鎴愬姛',
-                  duration: 2
-                })
-                document.getElementsByClassName('menu-view')[0].classList.remove('saving')
-                MKEmitter.emit('updateCustomComponent')
-              } else {
-                this.setState({loading: false})
-                notification.warning({
-                  top: 92,
-                  message: response.message,
-                  duration: 5
-                })
-              }
-            })
-          } else {
-            this.setState({loading: false})
-            notification.warning({
-              top: 92,
-              message: result.ErrMesg,
-              duration: 5
-            })
-          }
+      this.setState({loading: true})
+      setTimeout(() => {
+        let template = this.getUserComponent()
+        html2canvas(document.getElementById(config.uuid)).then(canvas => {
+          let img = canvas.toDataURL('image/png') // 鑾峰彇鐢熸垚鐨勫浘鐗�
+          Api.fileuploadbase64(img, 'cloud').then(result => {
+            if (result.status) {
+              Api.getSystemConfig({
+                func: 's_custom_components_adduptdel',
+                c_id: config.uuid,
+                images: Utils.getcloudurl(result.Images),
+                c_name: res.name,
+                long_param: window.btoa(window.encodeURIComponent(JSON.stringify(template))),
+                del_type: ''
+              }).then(response => {
+                if (response.status) {
+                  this.setState({loading: false, visible: false})
+                  notification.success({
+                    top: 92,
+                    message: '淇濆瓨鎴愬姛',
+                    duration: 2
+                  })
+                  document.getElementsByClassName('menu-view')[0].classList.remove('saving')
+                  MKEmitter.emit('updateCustomComponent')
+                } else {
+                  this.setState({loading: false})
+                  notification.warning({
+                    top: 92,
+                    message: response.message,
+                    duration: 5
+                  })
+                }
+              })
+            } else {
+              this.setState({loading: false})
+              notification.warning({
+                top: 92,
+                message: result.ErrMesg,
+                duration: 5
+              })
+            }
+          })
         })
-      })
+      }, 300)
     })
   }
 
diff --git a/src/menu/components/share/usercomponent/settingform/index.jsx b/src/menu/components/share/usercomponent/settingform/index.jsx
index 50613ac..46f1ff3 100644
--- a/src/menu/components/share/usercomponent/settingform/index.jsx
+++ b/src/menu/components/share/usercomponent/settingform/index.jsx
@@ -69,6 +69,10 @@
                     {
                       required: true,
                       message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!'
+                    },
+                    {
+                      max: 15,
+                      message: '缁勪欢鍚嶇О鏈�澶�15涓瓧绗�!'
                     }
                   ]
                 })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit}/>)}
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index dcd3573..d6989a2 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -19,6 +19,7 @@
 const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
+const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const ColumnComponent = asyncComponent(() => import('./columns'))
@@ -53,7 +54,7 @@
         pageable: true,     // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
         switchable: true,   // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
         dataName: card.dataName || '',
-        width: 24,
+        width: card.width || 24,
         search: [
           { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'text', match: 'like' },
           { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'select', match: 'equal' },
@@ -67,7 +68,7 @@
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: 24, bordered: 'true', tableType: 'checkbox' },
+        wrap: { name: card.name, width: card.width || 24, bordered: 'true', tableType: 'checkbox' },
         style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
         headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
         columns: [],
@@ -78,6 +79,41 @@
         ],
         scripts: [],
         btnlog: [],
+      }
+
+      if (card.config) {
+        let config = fromJS(card.config).toJS()
+
+        _card.wrap = config.wrap
+        _card.wrap.name = card.name
+        _card.style = config.style
+        _card.headerStyle = config.headerStyle
+
+        _card.action = config.action.map(item => {
+          item.uuid = Utils.getuuid()
+          return item
+        })
+        _card.search = config.search.map(item => {
+          item.uuid = Utils.getuuid()
+          return item
+        })
+        _card.cols = config.cols.map(col => {
+          col.uuid = Utils.getuuid()
+          if (col.type === 'colspan' && col.subcols) {
+            col = this.loopCol(col)
+          } else if (col.type === 'custom' && col.elements) {
+            col.elements = col.elements.map(cell => {
+              cell.uuid = Utils.getuuid()
+              return cell
+            })
+          } else if (col.type === 'action' && col.elements) {
+            col.elements = col.elements.map(cell => {
+              cell.uuid = Utils.getuuid()
+              return cell
+            })
+          }
+          return col
+        })
       }
       
       this.setState({
@@ -111,6 +147,23 @@
     MKEmitter.removeListener('submitStyle', this.getStyle)
     MKEmitter.removeListener('submitModal', this.handleSave)
     MKEmitter.removeListener('logButton', this.logButton)
+  }
+
+  loopCol = (col) => {
+    col.subcols = col.subcols.map(c => {
+      c.uuid = Utils.getuuid()
+      if (c.type === 'colspan' && c.subcols) {
+        c = this.loopCol(c)
+      } else if (c.type === 'custom' && c.elements) {
+        c.elements = c.elements.map(cell => {
+          cell.uuid = Utils.getuuid()
+          return cell
+        })
+      }
+      return c
+    })
+
+    return col
   }
 
   /**
@@ -341,6 +394,7 @@
             <PasteComponent config={card} options={['action', 'search', 'form', 'cols']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            <UserComponent config={card}/>
             <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent} />
           </div>
diff --git a/src/menu/header/index.jsx b/src/menu/header/index.jsx
index 7087ee9..c1234dd 100644
--- a/src/menu/header/index.jsx
+++ b/src/menu/header/index.jsx
@@ -2,11 +2,11 @@
 import { is, fromJS } from 'immutable'
 
 import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
 import './index.scss'
 
 class MenuHeader extends Component {
   state = {
-    logourl: window.GLOB.mainlogo,
     avatar: sessionStorage.getItem('CloudAvatar') || avatar,
     userName: sessionStorage.getItem('CloudUserName')
   }
@@ -19,7 +19,7 @@
 
     return (
       <header className="menu-header-container">
-        <div className="header-logo"><img src={this.state.logourl} alt=""/></div>
+        <div className="header-logo"><img src={MainLogo} alt=""/></div>
           <div className="header-setting">
             <img src={this.state.avatar} alt=""/>
             <span>
diff --git a/src/menu/modelsource/dragsource/index.jsx b/src/menu/modelsource/dragsource/index.jsx
index 6dc9678..0f13372 100644
--- a/src/menu/modelsource/dragsource/index.jsx
+++ b/src/menu/modelsource/dragsource/index.jsx
@@ -1,13 +1,14 @@
 import React from 'react'
 import { useDrag } from 'react-dnd'
+import { Icon } from 'antd'
 import './index.scss'
 
-const MobSourceElement = ({content}) => {
-  const [, drag] = useDrag({ item: content })
+const MobSourceElement = ({item, triggerDel}) => {
+  const [, drag] = useDrag({ item })
   return (
     <div className="menu-source-item">
-      <div className="property"><span>{content.title}</span></div>
-      <img ref={drag} src={content.url} alt=""/>
+      <div className="property"><span>{item.title}</span>{item.config ? <Icon onClick={() => triggerDel(item)} type="close-circle" /> : null}</div>
+      <img ref={drag} src={item.url} alt=""/>
     </div>
   )
 }
diff --git a/src/menu/modelsource/dragsource/index.scss b/src/menu/modelsource/dragsource/index.scss
index a362607..ac891ba 100644
--- a/src/menu/modelsource/dragsource/index.scss
+++ b/src/menu/modelsource/dragsource/index.scss
@@ -8,6 +8,15 @@
   .property {
     font-size: 14px;
     color: rgba(0, 0, 0, 0.65);
+    margin-bottom: 2px;
+
+    .anticon-close-circle {
+      opacity: 0;
+      cursor: pointer;
+      padding: 0 3px;
+      color: #ff4d4f;
+      transition: all 0.3s;
+    }
   }
 
   img {
@@ -23,6 +32,12 @@
   }
 }
 
+.menu-source-item:hover .property {
+  .anticon-close-circle {
+    opacity: 1;
+  }
+}
+
 .menu-source-tooltip-box {
   margin-left: 20px;
   .ant-tooltip-content {
diff --git a/src/menu/modelsource/index.jsx b/src/menu/modelsource/index.jsx
index 21d2a4c..03f268a 100644
--- a/src/menu/modelsource/index.jsx
+++ b/src/menu/modelsource/index.jsx
@@ -1,9 +1,14 @@
 import React, {Component} from 'react'
 import { is, fromJS } from 'immutable'
+import { Modal, notification } from 'antd'
 
+import Api from '@/api'
 import { menuOptions } from './option'
 import SourceWrap from './dragsource'
+import MKEmitter from '@/utils/events.js'
 import './index.scss'
+
+const { confirm } = Modal
 
 class ModelSource extends Component {
   state = {
@@ -27,8 +32,53 @@
     })
   }
 
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (nextProps.components && !is(fromJS(this.props.components), fromJS(nextProps.components))) {
+      this.setState({
+        menuOptions: fromJS(nextProps.components).toJS()
+      })
+    }
+  }
+
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  triggerDel = (item) => {
+    confirm({
+      title: `纭畾鍒犻櫎<${item.title}>鍚楋紵`,
+      content: '',
+      onOk() {
+        return new Promise(resolve => {
+          Api.getSystemConfig({
+            func: 's_custom_components_adduptdel',
+            c_id: item.uuid,
+            images: '',
+            c_name: item.title,
+            long_param: '',
+            del_type: 'Y'
+          }).then(result => {
+            if (result.status) {
+              notification.success({
+                top: 92,
+                message: '鍒犻櫎鎴愬姛锛�',
+                duration: 5
+              })
+
+              MKEmitter.emit('updateCustomComponent')
+            } else {
+              notification.warning({
+                top: 92,
+                message: result.message,
+                duration: 5
+              })
+            }
+            resolve()
+          })
+        })
+      },
+      onCancel() {}
+    })
   }
 
   render() {
@@ -36,7 +86,7 @@
 
     return (
       <div className="mob-card-source-box">
-        {menuOptions.map((item, index) => (<SourceWrap key={index} content={item} />))}
+        {menuOptions.map((item, index) => (<SourceWrap key={index} item={item} triggerDel={this.triggerDel} />))}
       </div>
     )
   }
diff --git a/src/menu/modelsource/option.jsx b/src/menu/modelsource/option.jsx
index a47720f..7a55036 100644
--- a/src/menu/modelsource/option.jsx
+++ b/src/menu/modelsource/option.jsx
@@ -16,17 +16,17 @@
 // 缁勪欢閰嶇疆淇℃伅
 export const menuOptions = [
   { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '鏍囩椤�', width: 24, forbid: ['billPrint'] },
-  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '鍒嗙粍', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '鎼滅储鏉′欢', width: 24, forbid: ['billPrint'] },
-  { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', config: '' },
-  { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', config: '' },
+  { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 },
+  { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 },
   { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 },
   { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '琛ㄦ牸', width: 12 },
-  { type: 'menu', url: line, component: 'line', subtype: 'line', title: '鎶樼嚎鍥�' },
-  { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '闃舵鎶樼嚎鍥�' },
-  { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '鏌辩姸鍥�' },
-  { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '鏉″舰鍥�' },
+  { type: 'menu', url: line, component: 'line', subtype: 'line', title: '鎶樼嚎鍥�', width: 24 },
+  { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '闃舵鎶樼嚎鍥�', width: 24 },
+  { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '鏌辩姸鍥�', width: 24 },
+  { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '鏉″舰鍥�', width: 24 },
   { type: 'menu', url: Pie, component: 'pie', subtype: 'pie', title: '楗煎浘', width: 12 },
   { type: 'menu', url: Pie1, component: 'pie', subtype: 'ring', title: '鐜浘', width: 12 },
   { type: 'menu', url: Pie2, component: 'pie', subtype: 'nightingale', title: '鍗椾竵鏍煎皵鍥�', width: 12 },
+  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '鍒嗙粍', width: 24, forbid: ['billPrint'] },
 ]
diff --git a/src/mob/header/index.jsx b/src/mob/header/index.jsx
index 5c5383e..34db685 100644
--- a/src/mob/header/index.jsx
+++ b/src/mob/header/index.jsx
@@ -9,6 +9,7 @@
 import zhCN from '@/locales/zh-CN/mob.js'
 import enUS from '@/locales/en-US/mob.js'
 import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
 import './index.scss'
 
 const { confirm } = Modal
@@ -23,7 +24,6 @@
 
   state = {
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    logourl: window.GLOB.mainlogo,
     avatar: sessionStorage.getItem('CloudAvatar') || avatar,
     userName: sessionStorage.getItem('CloudUserName')
   }
@@ -52,7 +52,7 @@
 
     return (
       <header className="mob-header-container">
-        <div className="header-logo"><img src={this.state.logourl} alt=""/></div>
+        <div className="header-logo"><img src={MainLogo} alt=""/></div>
         {view === 'manage' ?
           <div className="mob-manage-title">
             搴旂敤绠$悊
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index 4b3fa72..feb862e 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -471,8 +471,12 @@
         cell: EditableCell
       }
     }
+
+    let moveprops = {}
     if (actions.includes('move')) {
       components.body.row = DragableBodyRow
+      moveprops.moveAble = !this.state.editingKey
+      moveprops.moveRow = this.moveRow
     }
     
     const columns = this.state.columns.map(col => {
@@ -509,8 +513,7 @@
               pagination={false}
               onRow={(record, index) => ({
                 index,
-                moveAble: !this.state.editingKey,
-                moveRow: this.moveRow,
+                ...moveprops
               })}
             />
           </DndProvider>
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 00c7f8a..b09c3fb 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -145,6 +145,7 @@
             url: item.images,
             component: config.type,
             subtype: config.subtype,
+            width: config.width || 24,
             config
           })
         })

--
Gitblit v1.8.0