From 5891206952e2ff63e87aed2f47df5324b019d32e Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 25 十月 2022 00:39:38 +0800
Subject: [PATCH] 2022-10-25

---
 src/tabviews/zshare/normalTable/index.jsx                                |    1 
 src/utils/utils-custom.js                                                |   21 
 src/tabviews/custom/components/share/normalTable/index.scss              |    5 
 src/templates/treepageconfig/index.jsx                                   |   25 
 src/menu/datasource/index.jsx                                            |    7 
 src/views/tabledesign/source.jsx                                         |    6 
 src/menu/components/table/normal-table/columns/editColumn/index.jsx      |    1 
 src/tabviews/basetable/index.jsx                                         |    5 
 src/menu/components/form/formaction/index.jsx                            |    4 
 src/views/mobdesign/index.jsx                                            |   82 +-
 src/views/tabledesign/index.scss                                         |   41 
 src/views/menudesign/index.jsx                                           |  176 +++--
 src/views/menudesign/popview/menuform/index.jsx                          |   98 ++
 src/tabviews/custom/components/card/cardcellList/index.jsx               |    1 
 src/menu/tableshell/index.jsx                                            |    1 
 src/menu/components/card/cardcellcomponent/index.jsx                     |   13 
 src/menu/components/share/actioncomponent/formconfig.jsx                 |    2 
 src/templates/calendarconfig/index.jsx                                   |   24 
 src/templates/subtableconfig/index.jsx                                   |   24 
 src/menu/components/card/data-card/index.jsx                             |   25 
 src/views/popdesign/index.jsx                                            |   17 
 src/views/menudesign/index.scss                                          |    6 
 src/views/imdesign/index.jsx                                             |   58 
 src/menu/components/table/normal-table/index.jsx                         |   22 
 src/templates/sharecomponent/treesettingcomponent/index.jsx              |    6 
 src/menu/components/table/edit-table/columns/index.jsx                   |    6 
 src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx |   23 
 src/menu/modalconfig/controller.jsx                                      |    2 
 src/templates/sharecomponent/settingcomponent/index.jsx                  |    9 
 src/views/menudesign/popview/index.jsx                                   |  283 ++++++++
 src/menu/components/tabs/table-tabs/options.jsx                          |   27 
 src/templates/comtableconfig/index.jsx                                   |   25 
 src/menu/components/table/base-table/columns/editColumn/formconfig.jsx   |   23 
 src/menu/components/tabs/table-tabs/index.jsx                            |    4 
 src/menu/components/form/simple-form/options.jsx                         |   13 
 src/views/tabledesign/index.jsx                                          |  280 ++------
 src/tabviews/zshare/actionList/index.jsx                                 |    1 
 src/tabviews/custom/components/share/normalTable/index.jsx               |  133 ++-
 src/menu/components/form/step-form/options.jsx                           |   13 
 src/templates/sharecomponent/settingcalcomponent/index.jsx               |    6 
 src/menu/components/table/edit-table/index.jsx                           |   22 
 src/menu/sysinterface/index.jsx                                          |   37 +
 src/tabviews/zshare/actionList/tabbutton/index.jsx                       |    7 
 src/menu/components/table/base-table/columns/editColumn/index.jsx        |    9 
 src/views/pcdesign/index.jsx                                             |   98 +-
 src/views/menudesign/popview/menuform/index.scss                         |    0 
 src/menu/components/table/base-table/options.jsx                         |    2 
 src/menu/components/tabs/table-tabs/index.scss                           |    9 
 src/menu/components/share/actioncomponent/index.jsx                      |   50 +
 src/menu/modulecell/index.jsx                                            |    3 
 src/mob/modalconfig/controller.jsx                                       |    2 
 src/templates/sharecomponent/actioncomponent/index.jsx                   |    6 
 src/menu/components/table/base-table/index.jsx                           |   24 
 src/views/menudesign/popview/index.scss                                  |  174 +++++
 54 files changed, 1,233 insertions(+), 729 deletions(-)

diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 520b227..f784bca 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -505,7 +505,6 @@
       profVisible: true,
       card: element
     })
-    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -529,8 +528,6 @@
       }, () => {
         this.props.updateElement(_elements)
       })
-
-      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -563,18 +560,18 @@
     }
   }
 
-  handleSave = (_cards, btn, modal) => {
+  handleSave = (componentId, btnId, modal) => {
     const { cards } = this.props
     const { elements } = this.state
 
-    if (cards.uuid !== _cards.uuid) return
+    if (cards.uuid !== componentId) return
     
-    let _index = elements.findIndex(cell => cell.uuid === btn.uuid)
+    let _index = elements.findIndex(cell => cell.uuid === btnId)
 
     if (_index === -1) return
 
     let _elements = elements.map(cell => {
-      if (cell.uuid === btn.uuid) {
+      if (cell.uuid === btnId) {
         cell.modal = modal
       }
 
@@ -751,11 +748,9 @@
               if (this.verifyRef.handleCancel) {
                 this.verifyRef.handleCancel().then(() => {
                   this.setState({ profVisible: false })
-                  MKEmitter.emit('modalStatus', false)
                 })
               } else {
                 this.setState({ profVisible: false })
-                MKEmitter.emit('modalStatus', false)
               }
             }}
             destroyOnClose
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 7e33108..bc8b505 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -140,10 +140,6 @@
     }
   }
 
-  componentDidMount () {
-    MKEmitter.addListener('submitModal', this.handleSave)
-  }
-
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.state), fromJS(nextState))
   }
@@ -155,7 +151,6 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('submitModal', this.handleSave)
   }
 
   /**
@@ -401,26 +396,6 @@
     } else if (btn.OpenType === 'popview' && appType !== 'mob') {
       MKEmitter.emit('changePopview', card, btn)
     }
-  }
-
-  handleSave = (_cards, btn, modal) => {
-    let card = fromJS(this.state.card).toJS()
-
-    if (card.uuid !== _cards.uuid) return
-
-    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
-
-    if (_index === -1) return
-
-    card.action = card.action.map(cell => {
-      if (cell.uuid === btn.uuid) {
-        cell.modal = modal
-      }
-
-      return cell
-    })
-
-    this.updateComponent(card)
   }
 
   addCard = (copy) => {
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index 91ab639..c76bdcc 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -157,7 +157,6 @@
     this.setState({
       profVisible: true
     })
-    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -173,7 +172,6 @@
         profVisible: false
       })
       this.props.updateconfig(group)
-      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -256,11 +254,9 @@
             if (this.verifyRef.handleCancel) {
               this.verifyRef.handleCancel().then(() => {
                 this.setState({ profVisible: false })
-                MKEmitter.emit('modalStatus', false)
               })
             } else {
               this.setState({ profVisible: false })
-              MKEmitter.emit('modalStatus', false)
             }
           }}
           destroyOnClose
diff --git a/src/menu/components/form/simple-form/options.jsx b/src/menu/components/form/simple-form/options.jsx
index 12b0542..4d87e6f 100644
--- a/src/menu/components/form/simple-form/options.jsx
+++ b/src/menu/components/form/simple-form/options.jsx
@@ -140,6 +140,19 @@
     },
     {
       type: 'radio',
+      field: 'goback',
+      label: '绌哄�艰繑鍥�',
+      initval: wrap.goback || 'false',
+      tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岃繑鍥炰笂涓�鐣岄潰銆�',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'radio',
       field: 'permission',
       label: '鏉冮檺楠岃瘉',
       initval: wrap.permission || 'false',
diff --git a/src/menu/components/form/step-form/options.jsx b/src/menu/components/form/step-form/options.jsx
index 403fa82..d52824e 100644
--- a/src/menu/components/form/step-form/options.jsx
+++ b/src/menu/components/form/step-form/options.jsx
@@ -103,6 +103,19 @@
     },
     {
       type: 'radio',
+      field: 'goback',
+      label: '绌哄�艰繑鍥�',
+      initval: wrap.goback || 'false',
+      tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岃繑鍥炰笂涓�鐣岄潰銆�',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'radio',
       field: 'permission',
       label: '鏉冮檺楠岃瘉',
       initval: wrap.permission || 'false',
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 148af17..1ebc0eb 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1068,6 +1068,8 @@
   ]
 
   let pageTemps = [
+    // { value: 'print', text: '鏍囩鎵撳嵃妯℃澘' },
+    // { value: 'billprintTemp', text: '鍗曟嵁鎵撳嵃妯℃澘' },
     { value: 'billprint', text: '鍗曟嵁鎵撳嵃' },
     { value: 'pay', text: '鏀粯' },
     { value: 'custom', text: '鑷畾涔�' }
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 0f29f3c..2bee4a7 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -60,17 +60,9 @@
   }
 
   componentDidMount () {
+    MKEmitter.addListener('revert', this.revert)
     MKEmitter.addListener('addButton', this.addButton)
-  }
-
-  /**
-   * @description 鐩戝惉鍒版寜閽鍒舵椂锛岃Е鍙戞寜閽紪杈�
-   */
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    const { actionlist } = this.state
-    if (!is(fromJS(nextProps.config.action), fromJS(this.props.config.action)) && !is(fromJS(nextProps.config.action), fromJS(actionlist))) {
-      this.setState({actionlist: fromJS(nextProps.config.action).toJS()})
-    }
+    MKEmitter.addListener('submitModal', this.handleSave)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -84,7 +76,41 @@
     this.setState = () => {
       return
     }
+    MKEmitter.removeListener('revert', this.revert)
     MKEmitter.removeListener('addButton', this.addButton)
+    MKEmitter.removeListener('submitModal', this.handleSave)
+  }
+
+  revert = () => {
+    this.setState({
+      actionlist: fromJS(this.props.config.action).toJS()
+    })
+  }
+
+  handleSave = (componentId, btnId, modal) => {
+    const { config } = this.props
+
+    if (config.uuid !== componentId) return
+
+    const { actionlist } = this.state
+
+    let _index = actionlist.findIndex(cell => cell.uuid === btnId)
+
+    if (_index === -1) return
+
+    let _actionlist = actionlist.map(cell => {
+      if (cell.uuid === btnId) {
+        cell.modal = modal
+      }
+
+      return cell
+    })
+
+    this.setState({
+      actionlist: _actionlist
+    }, () => {
+      this.props.updateaction({...config, action: _actionlist})
+    })
   }
 
   getStyle = (style) => {
@@ -323,7 +349,6 @@
       profVisible: true,
       card: element
     })
-    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -351,7 +376,6 @@
       }, () => {
         this.props.updateaction({...config, action: _actionlist})
       })
-      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -555,11 +579,9 @@
             if (this.verifyRef.handleCancel) {
               this.verifyRef.handleCancel().then(() => {
                 this.setState({ profVisible: false })
-                MKEmitter.emit('modalStatus', false)
               })
             } else {
               this.setState({ profVisible: false })
-              MKEmitter.emit('modalStatus', false)
             }
           }}
           destroyOnClose
diff --git a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
index 6897370..fb7d992 100644
--- a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
@@ -36,6 +36,9 @@
     value: 'picture',
     text: '鍥剧墖'
   }, {
+    value: 'video',
+    text: '瑙嗛'
+  }, {
     value: 'link',
     text: '閾炬帴'
   }, {
@@ -163,6 +166,26 @@
       }]
     },
     {
+      type: 'number',
+      key: 'startTime',
+      precision: 0,
+      label: '寮�濮嬫椂闂�',
+      initVal: card.startTime || 0,
+      tooltip: '瑙嗛寮�濮嬫挱鏀剧殑鏃堕棿锛岀敤浜庤皟鏁磋棰戝垵濮嬪寲灞曠ず鐨勭晫闈€��',
+      required: false
+    },
+    {
+      type: 'select',
+      key: 'aspectRatio',
+      label: '闀垮姣�',
+      initVal: card.aspectRatio || '16:9',
+      required: true,
+      options: [
+        { value: '4:3', text: '4:3' },
+        { value: '16:9', text: '16:9' }
+      ]
+    },
+    {
       type: 'radio',
       key: 'rowspan',
       label: '琛屽悎骞�',
diff --git a/src/menu/components/table/base-table/columns/editColumn/index.jsx b/src/menu/components/table/base-table/columns/editColumn/index.jsx
index cbb8ac4..9d7bf5f 100644
--- a/src/menu/components/table/base-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/base-table/columns/editColumn/index.jsx
@@ -10,11 +10,12 @@
 
 const { TextArea } = Input
 const columnTypeOptions = {
-  text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'blacklist', 'perspective', 'rowspan'],
+  text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'fieldlength', 'blacklist', 'perspective', 'rowspan'],
   number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'blacklist', 'perspective', 'sum', 'rowspan'],
-  link: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'joint', 'Width', 'blacklist', 'nameField'],
-  textarea: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'blacklist'],
-  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'blacklist', 'scale', 'lenWidRadio', 'span'],
+  link: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'joint', 'Width', 'fieldlength', 'blacklist', 'nameField'],
+  textarea: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'prefix', 'postfix', 'blacklist'],
+  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale', 'lenWidRadio', 'span'],
+  video: ['label', 'field', 'type', 'Align', 'Hide', 'startTime', 'Width', 'fieldlength', 'blacklist', 'aspectRatio'],
   colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
   custom: ['label', 'type', 'Align', 'Hide', 'Width', 'blacklist'],
   action: ['label', 'type', 'Align', 'Width'],
diff --git a/src/menu/components/table/base-table/index.jsx b/src/menu/components/table/base-table/index.jsx
index f4a90c1..ef4980f 100644
--- a/src/menu/components/table/base-table/index.jsx
+++ b/src/menu/components/table/base-table/index.jsx
@@ -78,7 +78,6 @@
   }
 
   componentDidMount () {
-    MKEmitter.addListener('submitModal', this.handleSave)
     MKEmitter.addListener('completeSave', this.completeSave)
   }
 
@@ -93,7 +92,6 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('submitModal', this.handleSave)
     MKEmitter.removeListener('completeSave', this.completeSave)
   }
 
@@ -262,26 +260,6 @@
     }
   }
 
-  handleSave = (_cards, btn, modal) => {
-    let card = fromJS(this.state.card).toJS()
-
-    if (card.uuid !== _cards.uuid) return
-
-    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
-
-    if (_index === -1) return
-
-    card.action = card.action.map(cell => {
-      if (cell.uuid === btn.uuid) {
-        cell.modal = modal
-      }
-
-      return cell
-    })
-
-    this.updateComponent(card)
-  }
-
   getWrapForms = () => {
     const { wrap, action, columns, cols } = this.state.card
 
@@ -317,7 +295,7 @@
     config.absFields = []
     config.cols.forEach(col => {
       if (!col.field) return
-      if (['text', 'picture', 'textarea'].includes(col.type)) {
+      if (['text', 'picture', 'video', 'textarea'].includes(col.type)) {
         config.columns.push({
           datatype: `Nvarchar(${col.fieldlength || 50})`,
           field: col.field,
diff --git a/src/menu/components/table/base-table/options.jsx b/src/menu/components/table/base-table/options.jsx
index 3af1d39..6a9c6c7 100644
--- a/src/menu/components/table/base-table/options.jsx
+++ b/src/menu/components/table/base-table/options.jsx
@@ -72,7 +72,7 @@
       field: 'tableMode',
       label: '鍔犺浇妯″紡',
       initval: wrap.tableMode || 'compatible',
-      tooltip: '浣跨敤鎬ラ�熸ā寮忔椂锛岃〃鏍间腑鐨勬爣璁般�佸弻鍑讳簨浠躲�佹牸寮忓寲銆佽鍚堝苟銆佸墠缂�銆佸悗缂�銆佸瓧娈甸�忚绛夋晥鏋滃皢鏃犳晥锛屼笖鏁版嵁閮戒細浠ユ枃鏈牸寮忔樉绀恒��',
+      tooltip: '浣跨敤鎬ラ�熸ā寮忔椂锛岃〃鏍间腑鐨勬爣璁般�佸弻鍑讳簨浠躲�佹牸寮忓寲銆佽鍚堝苟銆佸垪鍚堝苟銆佸墠缂�銆佸悗缂�銆佸瓧娈甸�忚绛夋晥鏋滃皢鏃犳晥锛屼笖鏁版嵁閮戒細浠ユ枃鏈牸寮忔樉绀恒��',
       required: false,
       options: [
         {value: 'compatible', label: '鍏煎'},
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index ccb4fbd..dbb0c1a 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -262,14 +262,12 @@
     let _columns = fromJS(this.state.columns).toJS()
     let type = item.subType
 
-    if (item.subType === 'link' || item.subType === 'colspan' || item.subType === 'picture') {
+    if (!['text', 'number', 'textarea', 'custom', 'action', 'formula', 'index'].includes(item.subType)) {
       type = 'text'
     }
 
     let col = { focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: type, elements: [] }
-    if (col.type === 'colspan') {
-      col.subcols = []
-    } else if (col.type === 'action') {
+    if (col.type === 'action') {
       col.label = '鎿嶄綔'
     } else if (col.type === 'index') {
       col.label = '搴忓彿'
diff --git a/src/menu/components/table/edit-table/index.jsx b/src/menu/components/table/edit-table/index.jsx
index 089f718..f6d6d6c 100644
--- a/src/menu/components/table/edit-table/index.jsx
+++ b/src/menu/components/table/edit-table/index.jsx
@@ -119,7 +119,6 @@
   }
 
   componentDidMount () {
-    MKEmitter.addListener('submitModal', this.handleSave)
     MKEmitter.addListener('completeSave', this.completeSave)
   }
 
@@ -134,7 +133,6 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('submitModal', this.handleSave)
     MKEmitter.removeListener('completeSave', this.completeSave)
   }
 
@@ -314,26 +312,6 @@
     } else if (btn.OpenType === 'popview') {
       MKEmitter.emit('changePopview', card, btn)
     }
-  }
-
-  handleSave = (_cards, btn, modal) => {
-    let card = fromJS(this.state.card).toJS()
-
-    if (card.uuid !== _cards.uuid) return
-
-    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
-
-    if (_index === -1) return
-
-    card.action = card.action.map(cell => {
-      if (cell.uuid === btn.uuid) {
-        cell.modal = modal
-      }
-
-      return cell
-    })
-
-    this.updateComponent(card)
   }
 
   getWrapForms = () => {
diff --git a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
index e004eb9..7444d5f 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -43,6 +43,9 @@
     value: 'picture',
     text: '鍥剧墖'
   }, {
+    value: 'video',
+    text: '瑙嗛'
+  }, {
     value: 'link',
     text: '閾炬帴'
   }, {
@@ -175,6 +178,26 @@
       }]
     },
     {
+      type: 'number',
+      key: 'startTime',
+      precision: 0,
+      label: '寮�濮嬫椂闂�',
+      initVal: card.startTime || 0,
+      tooltip: '瑙嗛寮�濮嬫挱鏀剧殑鏃堕棿锛岀敤浜庤皟鏁磋棰戝垵濮嬪寲灞曠ず鐨勭晫闈€��',
+      required: false
+    },
+    {
+      type: 'select',
+      key: 'aspectRatio',
+      label: '闀垮姣�',
+      initVal: card.aspectRatio || '16:9',
+      required: true,
+      options: [
+        { value: '4:3', text: '4:3' },
+        { value: '16:9', text: '16:9' }
+      ]
+    },
+    {
       type: 'radio',
       key: 'rowspan',
       label: '琛屽悎骞�',
diff --git a/src/menu/components/table/normal-table/columns/editColumn/index.jsx b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
index cbb8ac4..eb2f413 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -15,6 +15,7 @@
   link: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'joint', 'Width', 'blacklist', 'nameField'],
   textarea: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'blacklist'],
   picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'blacklist', 'scale', 'lenWidRadio', 'span'],
+  video: ['label', 'field', 'type', 'Align', 'Hide', 'startTime', 'Width', 'blacklist', 'aspectRatio'],
   colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
   custom: ['label', 'type', 'Align', 'Hide', 'Width', 'blacklist'],
   action: ['label', 'type', 'Align', 'Width'],
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index 8f8f6a3..767e8e9 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -138,7 +138,6 @@
   }
 
   componentDidMount () {
-    MKEmitter.addListener('submitModal', this.handleSave)
     MKEmitter.addListener('completeSave', this.completeSave)
   }
 
@@ -153,7 +152,6 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('submitModal', this.handleSave)
     MKEmitter.removeListener('completeSave', this.completeSave)
   }
 
@@ -366,26 +364,6 @@
     } else if (btn.OpenType === 'popview') {
       MKEmitter.emit('changePopview', card, btn)
     }
-  }
-
-  handleSave = (_cards, btn, modal) => {
-    let card = fromJS(this.state.card).toJS()
-
-    if (card.uuid !== _cards.uuid) return
-
-    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
-
-    if (_index === -1) return
-
-    card.action = card.action.map(cell => {
-      if (cell.uuid === btn.uuid) {
-        cell.modal = modal
-      }
-
-      return cell
-    })
-
-    this.updateComponent(card)
   }
 
   getWrapForms = () => {
diff --git a/src/menu/components/tabs/table-tabs/index.jsx b/src/menu/components/tabs/table-tabs/index.jsx
index 5356b0f..1536bc0 100644
--- a/src/menu/components/tabs/table-tabs/index.jsx
+++ b/src/menu/components/tabs/table-tabs/index.jsx
@@ -188,7 +188,7 @@
     editab.label = res.label
     editab.icon = res.icon
     editab.hide = res.hide || 'false'
-    editab.blacklist = res.blacklist
+    editab.permission = res.permission || 'false'
     editab.components[0].name = res.label
 
     if (editab.uuid) {
@@ -225,7 +225,7 @@
     const { tabs } = this.state
 
     return (
-      <div className="menu-tabs-edit-box" style={tabs.style} id={tabs.uuid}>
+      <div className="table-tabs-edit-box" style={tabs.style} id={tabs.uuid}>
         <DraggableTabs tabsMove={this.moveSwitch} tabsDrop={this.dropTable}>
           {tabs.subtabs.map((tab, i) => (
             <TabPane tab={
diff --git a/src/menu/components/tabs/table-tabs/index.scss b/src/menu/components/tabs/table-tabs/index.scss
index 9f77d18..af40884 100644
--- a/src/menu/components/tabs/table-tabs/index.scss
+++ b/src/menu/components/tabs/table-tabs/index.scss
@@ -1,11 +1,4 @@
-.menu-tabs-edit-box {
-  position: relative;
-  box-sizing: border-box;
-  background: #ffffff;
-  background-position: center center;
-  background-repeat: no-repeat;
-  background-size: cover;
-
+.table-tabs-edit-box {
   .ant-tabs-top-bar {
     margin-bottom: 0;
   }
diff --git a/src/menu/components/tabs/table-tabs/options.jsx b/src/menu/components/tabs/table-tabs/options.jsx
index 3793f20..77e10ac 100644
--- a/src/menu/components/tabs/table-tabs/options.jsx
+++ b/src/menu/components/tabs/table-tabs/options.jsx
@@ -2,18 +2,6 @@
  * @description tab琛ㄥ崟閰嶇疆淇℃伅
  */
 export function getTabForm(tab) {
-  let roleList = sessionStorage.getItem('sysRoles')
-
-  if (roleList) {
-    try {
-      roleList = JSON.parse(roleList)
-    } catch (e) {
-      roleList = []
-    }
-  } else {
-    roleList = []
-  }
-
   const tabForm = [
     {
       type: 'text',
@@ -43,13 +31,16 @@
       ],
     },
     {
-      type: 'multiselect',
-      field: 'blacklist',
-      label: '榛戝悕鍗�',
-      initval: tab.blacklist || [],
+      type: 'radio',
+      field: 'permission',
+      label: '鏉冮檺楠岃瘉',
+      initval: tab.permission || 'false',
       required: false,
-      options: roleList
-    },
+      options: [
+        {value: 'true', label: '鍚敤'},
+        {value: 'false', label: '绂佺敤'},
+      ]
+    }
   ]
 
   return tabForm
diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx
index 569dbba..52a1544 100644
--- a/src/menu/datasource/index.jsx
+++ b/src/menu/datasource/index.jsx
@@ -5,7 +5,6 @@
 import { SettingOutlined } from '@ant-design/icons'
 
 import VerifyCard from './verifycard'
-import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 class DataSource extends Component {
@@ -140,8 +139,6 @@
       visible: true,
       mainSearch: search
     })
-
-    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   verifySubmit = () => {
@@ -203,8 +200,6 @@
 
       this.setState({loading: false, visible: false})
       this.props.updateConfig({...config, ...res})
-
-      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({loading: false})
     })
@@ -226,7 +221,7 @@
           okText="鎻愪氦"
           onOk={this.verifySubmit}
           confirmLoading={loading}
-          onCancel={() => { MKEmitter.emit('modalStatus', false);this.setState({ visible: false }) }}
+          onCancel={() => {this.setState({ visible: false }) }}
           destroyOnClose
         >
           <VerifyCard
diff --git a/src/menu/modalconfig/controller.jsx b/src/menu/modalconfig/controller.jsx
index 881883d..683598d 100644
--- a/src/menu/modalconfig/controller.jsx
+++ b/src/menu/modalconfig/controller.jsx
@@ -47,7 +47,7 @@
   
   handleSave = (modal) => {
     const { config, btn } = this.state
-    MKEmitter.emit('submitModal', config, btn, modal)
+    MKEmitter.emit('submitModal', config.uuid, btn.uuid, modal)
   }
 
   render () {
diff --git a/src/menu/modulecell/index.jsx b/src/menu/modulecell/index.jsx
index e1c5fad..1117370 100644
--- a/src/menu/modulecell/index.jsx
+++ b/src/menu/modulecell/index.jsx
@@ -92,6 +92,7 @@
           { subType: 'text', text: '鏂囨湰', type: 'col', $init: true },
           { subType: 'number', text: '鏁板瓧', type: 'col', $init: true },
           { subType: 'picture', text: '鍥剧墖', type: 'col', $init: true },
+          { subType: 'video', text: '瑙嗛', type: 'col', $init: true },
           { subType: 'link', text: '閾炬帴', type: 'col', $init: true },
           { subType: 'textarea', text: '澶氳鏂囨湰', type: 'col', $init: true },
           { subType: 'custom', text: '鑷畾涔夊垪', type: 'col', $init: true },
@@ -139,7 +140,7 @@
 
     return (
       <div className="mk-source-box">
-        <div className="tip">娉細褰撴嫋鍔ㄧ被鍨嬩笉鍙楁敮鎸佹椂浼氳閲嶇疆銆�</div>
+        <div className="tip">娉細褰撳厓绱犵被鍨嬩笉鍙楁敮鎸佹椂浼氳閲嶇疆銆�</div>
         {options.map((item, index) => (<div className="mk-class" span={item.span} key={index}>
           <div className="title">{item.title}</div>
           {item.children.map(cell => <SourceWrap key={cell.value || cell.subType} item={cell}/>)}
diff --git a/src/menu/sysinterface/index.jsx b/src/menu/sysinterface/index.jsx
index 5269b49..240fea2 100644
--- a/src/menu/sysinterface/index.jsx
+++ b/src/menu/sysinterface/index.jsx
@@ -160,8 +160,44 @@
   changeScripts = (interfaces) => {
     const { config } = this.props
 
+    interfaces = interfaces.map(item => {
+      item.$tables = this.getTables(item)
+      return item
+    })
+
     this.setState({ interfaces })
     this.props.updateConfig({...config, interfaces})
+  }
+
+  getTables = (record) => {
+    let tables = []
+    let cuts = []
+    let cutreg = /(from|update|insert\s+into)\s+(@db@)?[a-z_]+/ig
+    let trimreg = /(from|update|insert\s+into)\s+(@db@)?/ig
+
+    if (record.setting.interType === 'system') {
+      if (record.setting.execute !== 'false') {
+        let tbs = record.setting.dataresource.match(cutreg)
+        tbs && cuts.push(...tbs)
+      }
+      record.scripts && record.scripts.forEach(script => {
+        if (script.status === 'false') return
+        let tbs = script.sql.match(cutreg)
+        tbs && cuts.push(...tbs)
+      })
+    } else {
+      let tb = record.setting.tableName.replace(/@db@|\s+/ig, '')
+      if (/[a-z_]+/ig.test(tb)) {
+        tables.push(tb)
+      }
+    }
+
+    cuts = cuts.map(item => item.replace(trimreg, ''))
+    tables.push(...cuts)
+    tables = tables.filter(Boolean)
+    tables = Array.from(new Set(tables))
+
+    return tables
   }
 
   update = (record) => {
@@ -173,6 +209,7 @@
       record.status = 'false'
     }
     record.name = record.setting.name
+    record.$tables = this.getTables(record)
 
     let interfaces = this.state.interfaces.map(item => {
       if (item.uuid !== record.uuid) {
diff --git a/src/menu/tableshell/index.jsx b/src/menu/tableshell/index.jsx
index 2e125ea..1f78877 100644
--- a/src/menu/tableshell/index.jsx
+++ b/src/menu/tableshell/index.jsx
@@ -95,6 +95,7 @@
     drop(item) {
       if (item.added || item.index) {
         delete item.added // 鍒犻櫎缁勪欢娣诲姞鏍囪
+        delete item.dropTargetId
         return
       }
       
diff --git a/src/mob/modalconfig/controller.jsx b/src/mob/modalconfig/controller.jsx
index efd36d6..96ddcd6 100644
--- a/src/mob/modalconfig/controller.jsx
+++ b/src/mob/modalconfig/controller.jsx
@@ -47,7 +47,7 @@
   
   handleSave = (modal) => {
     const { config, btn } = this.state
-    MKEmitter.emit('submitModal', config, btn, modal)
+    MKEmitter.emit('submitModal', config.uuid, btn.uuid, modal)
   }
 
   render () {
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index c6b9ade..e856616 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -238,10 +238,7 @@
 
       if (item.type === 'tabs') {
         item.subtabs = item.subtabs.filter(tab => {
-          if (
-            tab.blacklist && tab.blacklist.length > 0 &&
-            tab.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0
-          ) {
+          if (!skip && !permAction[tab.components[0].uuid] && tab.permission === 'true') {
             return false
           } else if (tab.hide === 'true') {
             return false
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index aa8772a..94cf90b 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -833,6 +833,7 @@
             <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
               <TabButton
                 btn={card}
+                BID={data.$$BID}
                 BData={data.$$BData || ''}
                 disabled={_disabled}
                 selectedData={_data}
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index 0e98c31..e35a7e9 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -15,8 +15,9 @@
 import './index.scss'
 
 const { Paragraph } = Typography
-const CardCellComponent = asyncComponent(() => import('@/tabviews/custom/components/card/cardcellList'))
+const Video = asyncComponent(() => import('@/components/video'))
 const MkPicture = asyncComponent(() => import('@/components/mkPicture'))
+const CardCellComponent = asyncComponent(() => import('@/tabviews/custom/components/card/cardcellList'))
 const PicRadio = {
   '4:3': '75%', '3:2': '66.67%', '16:9': '56.25%', '2:1': '50%', '3:1': '33.33%', '4:1': '25%',
   '5:1': '20%', '6:1': '16.67%', '7:1': '14.29%', '8:1': '12.5%', '9:1': '11.11%',
@@ -24,7 +25,7 @@
 }
 class BodyRow extends React.Component {
   shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.props.data), fromJS(nextProps.data)) || !is(fromJS(this.props.className), fromJS(nextProps.className))
+    return !is(fromJS(this.props.data), fromJS(nextProps.data)) || this.props.className !== nextProps.className
   }
 
   render() {
@@ -259,6 +260,14 @@
           ))}
         </div>
       )
+    } else if (col.type === 'video') {
+      let url = record[col.field] || ''
+
+      resProps.children = (
+        <div className="video-wrap">
+          {url ? <Video card={col} value={url}/> : null}
+        </div>
+      )
     } else if (col.type === 'textarea') {
       let content = ''
       if (record[col.field] !== undefined) {
@@ -434,52 +443,69 @@
       }
     }
 
-    let getColumns = (cols) => {
-      return cols.map(item => {
-        let cell = null
-  
-        if (item.type === 'colspan') {
-          cell = { title: item.label, align: item.Align }
-          cell.children = getColumns(item.subcols)
-        } else {
-          if (item.rowspan === 'true') {
-            rowspans.push(item.field)
-          }
-          if (item.type === 'index') {
-            item.field = '$Index'
-            item.type = 'text'
-          } else if (_format && !Math.floor(Math.random() * radio)) {
-            item.blur = true
-          }
-  
-          if (item.marks && item.marks.length === 0) {
-            item.marks = ''
-          }
+    let _columns = []
 
-          if (item.field) {
-            orderfields[item.uuid] = item.field
-          }
-
-          cell = {
-            align: item.Align,
-            dataIndex: item.uuid,
-            title: item.label,
-            sorter: item.field && item.IsSort === 'true',
-            width: item.Width || 120,
-            onCell: record => ({
-              record,
-              col: item,
-              config: item.type === 'custom' || item.type === 'action' ? {setting, columns: fields} : null,
-              triggerLink: this.triggerLink
-            })
-          }
-        }
+    if (setting.tableMode !== 'fast') {
+      let getColumns = (cols) => {
+        return cols.map(item => {
+          let cell = null
+    
+          if (item.type === 'colspan') {
+            cell = { title: item.label, align: item.Align }
+            cell.children = getColumns(item.subcols)
+          } else {
+            if (item.rowspan === 'true') {
+              rowspans.push(item.field)
+            }
+            if (item.type === 'index') {
+              item.field = '$Index'
+              item.type = 'text'
+            } else if (_format && !Math.floor(Math.random() * radio)) {
+              item.blur = true
+            }
+    
+            if (item.marks && item.marks.length === 0) {
+              item.marks = ''
+            }
   
-        return cell
+            if (item.field) {
+              orderfields[item.uuid] = item.field
+            }
+  
+            cell = {
+              align: item.Align,
+              dataIndex: item.uuid,
+              title: item.label,
+              sorter: item.field && item.IsSort === 'true',
+              width: item.Width || 120,
+              onCell: record => ({
+                record,
+                col: item,
+                config: item.type === 'custom' || item.type === 'action' ? {setting, columns: fields} : null,
+                triggerLink: this.triggerLink
+              })
+            }
+          }
+    
+          return cell
+        })
+      }
+      _columns = getColumns(columns)
+    } else {
+      let fields = []
+      columns.forEach(item => {
+        if (!item.field || fields.includes(item.field)) return
+        fields.push(item.field)
+
+        _columns.push({
+          align: item.Align,
+          dataIndex: item.field,
+          title: item.label,
+          sorter: item.IsSort === 'true',
+          width: item.Width || 120
+        })
       })
     }
-
-    let _columns = getColumns(columns)
 
     if (rowspans.length === 0) {
       rowspans = null
@@ -493,13 +519,6 @@
       }
       return uuid.join('')
     }) ()
-
-    // if (setting.borderColor) { // 杈规棰滆壊
-    //   let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${setting.borderColor}}`
-    //   let ele = document.createElement('style')
-    //   ele.innerHTML = style
-    //   document.getElementsByTagName('head')[0].appendChild(ele)
-    // }
 
     let size = (setting.pageSize || 10) + ''
     let pageOptions = ['10', '25', '50', '100', '500', '1000']
@@ -856,11 +875,14 @@
       }
     }
 
-    const components = {
+    let components = {
       body: {
-        row: BodyRow,
-        cell: BodyCell
+        row: BodyRow
       }
+    }
+
+    if (setting.tableMode !== 'fast') {
+      components.body.cell = BodyCell
     }
 
     // 鏁版嵁鏀惰捣鏃讹紝杩囨护宸查�夋暟鎹�
@@ -899,7 +921,6 @@
         }
         <Table
           components={components}
-          // style={setting.style}
           size={setting.size || 'middle'}
           bordered={setting.bordered !== 'false'}
           rowSelection={rowSelection}
@@ -909,7 +930,7 @@
           scroll={{ x: '100%', y: height }}
           onRow={(record, index) => {
             return {
-              lineMarks,
+              lineMarks: setting.tableMode !== 'fast' ? lineMarks : null,
               data: record,
               className: index === activeIndex ? ' mk-row-active ' : '',
               onClick: () => {this.changeRow(record, index)},
diff --git a/src/tabviews/custom/components/share/normalTable/index.scss b/src/tabviews/custom/components/share/normalTable/index.scss
index 697e60e..a339616 100644
--- a/src/tabviews/custom/components/share/normalTable/index.scss
+++ b/src/tabviews/custom/components/share/normalTable/index.scss
@@ -100,6 +100,11 @@
           position: relative;
           margin: 2px;
         }
+        .video-wrap {
+          .video-react-playback-rate {
+            display: none;
+          }
+        }
         .action-col {
           .ant-btn > .anticon + span {
             margin-left: 3px;
diff --git a/src/tabviews/zshare/actionList/index.jsx b/src/tabviews/zshare/actionList/index.jsx
index 6760ac3..3eb4181 100644
--- a/src/tabviews/zshare/actionList/index.jsx
+++ b/src/tabviews/zshare/actionList/index.jsx
@@ -99,6 +99,7 @@
             show={item.show || 'actionList'}
             disabled={lock || false}
             btn={item}
+            BID={BID}
             BData={BData}
             MenuID={MenuID}
             selectedData={selectedData}
diff --git a/src/tabviews/zshare/actionList/tabbutton/index.jsx b/src/tabviews/zshare/actionList/tabbutton/index.jsx
index ba8c96a..deea760 100644
--- a/src/tabviews/zshare/actionList/tabbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -12,6 +12,7 @@
 class TabButton extends Component {
   static propTpyes = {
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
+    BID: PropTypes.any,
     MenuID: PropTypes.string,         // 鑿滃崟ID
     btn: PropTypes.object,            // 鎸夐挳
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
@@ -108,7 +109,7 @@
    * @description 瑙﹀彂鎸夐挳鎿嶄綔
    */
   actionTrigger = (triggerId, record, type) => {
-    const { btn, selectedData } = this.props
+    const { btn, selectedData, BID } = this.props
     const { disabled } = this.state
 
     if (disabled) return
@@ -134,8 +135,8 @@
 
     if (btn.Ot === 'requiredSgl') {
       primaryId = data[0].$$uuid || ''
-    } else if (btn.Ot === 'notRequired' && data[0]) {
-      primaryId = data[0].$$BID || ''
+    } else if (btn.Ot === 'notRequired' && BID) {
+      primaryId = BID
     }
 
     let newtab = {}
diff --git a/src/tabviews/zshare/normalTable/index.jsx b/src/tabviews/zshare/normalTable/index.jsx
index e01df0a..eafacdb 100644
--- a/src/tabviews/zshare/normalTable/index.jsx
+++ b/src/tabviews/zshare/normalTable/index.jsx
@@ -780,6 +780,7 @@
                   btn={btn}
                   disabled={record.$disabled}
                   selectedData={[record]}
+                  BID={record.$$BID}
                   BData={this.props.BData}
                   MenuID={this.props.MenuID}
                 />
diff --git a/src/templates/calendarconfig/index.jsx b/src/templates/calendarconfig/index.jsx
index 72e72cb..2284223 100644
--- a/src/templates/calendarconfig/index.jsx
+++ b/src/templates/calendarconfig/index.jsx
@@ -52,7 +52,6 @@
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
     mockdata: [],            // 娴嬭瘯鏁版嵁
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -126,10 +125,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -142,7 +154,6 @@
         return false
       }
     }
-    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   getMockData = (year) => {
@@ -245,11 +256,6 @@
       return
     }
     document.onkeydown = () => {}
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   // 椤甸潰杩斿洖
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index 6717638..74e2368 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -61,7 +61,6 @@
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     chartview: null,         // 褰撳墠瑙嗗浘
     openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -163,10 +162,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -179,8 +191,6 @@
         return false
       }
     }
-
-    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   /**
@@ -191,11 +201,6 @@
       return
     }
     document.onkeydown = () => {}
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   /**
diff --git a/src/templates/sharecomponent/actioncomponent/index.jsx b/src/templates/sharecomponent/actioncomponent/index.jsx
index 4253f4d..976dd12 100644
--- a/src/templates/sharecomponent/actioncomponent/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/index.jsx
@@ -674,8 +674,6 @@
       profVisible: true,
       card: element
     })
-
-    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -703,8 +701,6 @@
       }, () => {
         this.props.updateaction({...config, action: _actionlist})
       })
-
-      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -950,11 +946,9 @@
             if (this.verifyRef.handleCancel) {
               this.verifyRef.handleCancel().then(() => {
                 this.setState({ profVisible: false })
-                MKEmitter.emit('modalStatus', false)
               })
             } else {
               this.setState({ profVisible: false })
-              MKEmitter.emit('modalStatus', false)
             }
           }}
           destroyOnClose
diff --git a/src/templates/sharecomponent/settingcalcomponent/index.jsx b/src/templates/sharecomponent/settingcalcomponent/index.jsx
index 646acee..d1d7909 100644
--- a/src/templates/sharecomponent/settingcalcomponent/index.jsx
+++ b/src/templates/sharecomponent/settingcalcomponent/index.jsx
@@ -5,7 +5,6 @@
 import { SettingOutlined } from '@ant-design/icons'
 
 import VerifyCard from './verifycard'
-import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 class DataSource extends Component {
@@ -36,7 +35,6 @@
     this.setState({
       visible: true
     })
-    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   verifySubmit = () => {
@@ -65,8 +63,6 @@
 
       this.setState({loading: false, visible: false})
       this.props.updateConfig({...config, ...res})
-
-      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({loading: false})
     })
@@ -87,7 +83,7 @@
           okText="鎻愪氦"
           onOk={this.verifySubmit}
           confirmLoading={loading}
-          onCancel={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false }) }}
+          onCancel={() => { this.setState({ visible: false }) }}
           destroyOnClose
         >
           <VerifyCard
diff --git a/src/templates/sharecomponent/settingcomponent/index.jsx b/src/templates/sharecomponent/settingcomponent/index.jsx
index 72e3a09..7f47893 100644
--- a/src/templates/sharecomponent/settingcomponent/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/index.jsx
@@ -5,7 +5,6 @@
 import { SettingOutlined } from '@ant-design/icons'
 
 import Utils, { FuncUtils } from '@/utils/utils.js'
-import MKEmitter from '@/utils/events.js'
 import SettingForm from './settingform'
 import CreateFunc from '@/templates/zshare/createfunc'
 import CreateInterface from '@/templates/zshare/createinterface'
@@ -48,8 +47,6 @@
       search: _search,
       menu: menu
     })
-
-    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   /**
@@ -70,8 +67,6 @@
       res.actionfixed = res.actionfixed === 'true'
 
       this.props.updatesetting({...config, setting: res})
-
-      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({
         loading: false
@@ -195,11 +190,11 @@
           visible={visible}
           width={'75vw'}
           maskClosable={false}
-          onCancel={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false, loading: false })}}
+          onCancel={() => { this.setState({ visible: false, loading: false })}}
           footer={[
             record && record.interType === 'system' ? <CreateInterface key="interface" loading={this.state.interloading} ref="tableCreatInterface" trigger={this.tableCreatInterface}/> : null,
             record && record.interType === 'inner' ? <CreateFunc key="create" ref="funcCreatComponent" trigger={this.tableCreatFunc}/> : null,
-            <Button key="cancel" onClick={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false, loading: false }) }}>鍙栨秷</Button>,
+            <Button key="cancel" onClick={() => { this.setState({ visible: false, loading: false }) }}>鍙栨秷</Button>,
             <Button key="confirm" type="primary" loading={this.state.loading} onClick={this.settingSave}>纭畾</Button>
           ]}
           destroyOnClose
diff --git a/src/templates/sharecomponent/treesettingcomponent/index.jsx b/src/templates/sharecomponent/treesettingcomponent/index.jsx
index 867f295..055a295 100644
--- a/src/templates/sharecomponent/treesettingcomponent/index.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/index.jsx
@@ -4,7 +4,6 @@
 import { SettingOutlined } from '@ant-design/icons'
 
 import SettingForm from './settingform'
-import MKEmitter from '@/utils/events.js'
 
 import './index.scss'
 
@@ -32,7 +31,6 @@
       visible: true,
       menu: menu
     })
-    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   /**
@@ -69,8 +67,6 @@
       res.searchLwidth = config.setting.searchLwidth !== undefined ? config.setting.searchLwidth : 33.3
 
       this.props.updatesetting({...config, setting: res})
-
-      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({
         loading: false
@@ -100,7 +96,7 @@
           visible={visible}
           width={'75vw'}
           maskClosable={false}
-          onCancel={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false })}}
+          onCancel={() => { this.setState({ visible: false })}}
           confirmLoading={loading}
           onOk={this.settingSave}
           destroyOnClose
diff --git a/src/templates/subtableconfig/index.jsx b/src/templates/subtableconfig/index.jsx
index c3d4de1..34c9408 100644
--- a/src/templates/subtableconfig/index.jsx
+++ b/src/templates/subtableconfig/index.jsx
@@ -63,7 +63,6 @@
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     chartview: null,         // 褰撳墠瑙嗗浘
     openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -149,10 +148,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -165,7 +177,6 @@
         return false
       }
     }
-    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   /**
@@ -226,11 +237,6 @@
       return
     }
     document.onkeydown = () => {}
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   // 椤甸潰杩斿洖
diff --git a/src/templates/treepageconfig/index.jsx b/src/templates/treepageconfig/index.jsx
index a030308..eab9619 100644
--- a/src/templates/treepageconfig/index.jsx
+++ b/src/templates/treepageconfig/index.jsx
@@ -10,7 +10,6 @@
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
 
-import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import MenuForm from '@/templates/comtableconfig/menuform'
 import SourceElement from '@/templates/zshare/dragsource'
@@ -43,7 +42,6 @@
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -127,10 +125,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -143,7 +154,6 @@
         return false
       }
     }
-    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   /**
@@ -154,11 +164,6 @@
       return
     }
     document.onkeydown = () => {}
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   /**
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index b783fc3..19c7836 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -939,7 +939,7 @@
 /**
  * @description 鑾峰彇琛ㄥ悕
  */
-export function getTables (config) {
+export function getTables (config, pops) {
   let tables = []
   let cuts = []
   let cutreg = /(from|update|insert\s+into)\s+(@db@)?[a-z_]+/ig
@@ -973,15 +973,21 @@
   } else if (config.subcards) {
     config.subcards.forEach(item => {
       item.elements.forEach(cell => {
-        if (cell.eleType === 'button' && ['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
+        if (cell.eleType !== 'button') return
+        if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
           action.push(cell)
+        } else if (pops && cell.OpenType === 'popview') {
+          pops.push({...cell, parentId: config.uuid})
         }
       })
   
       if (item.backElements && item.setting.type === 'multi') {
         item.backElements.forEach(cell => {
-          if (cell.eleType === 'button' && ['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
+          if (cell.eleType !== 'button') return
+          if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
             action.push(cell)
+          } else if (pops && cell.OpenType === 'popview') {
+            pops.push({...cell, parentId: config.uuid})
           }
         })
       }
@@ -992,20 +998,27 @@
       col.elements.forEach(cell => {
         if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
           action.push(cell)
+        } else if (pops && cell.OpenType === 'popview') {
+          pops.push({...cell, parentId: config.uuid})
         }
       })
     }
   })
 
   config.elements && config.elements.forEach(cell => {
-    if (cell.eleType === 'button' && ['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
+    if (cell.eleType !== 'button') return
+    if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
       action.push(cell)
+    } else if (pops && cell.OpenType === 'popview') {
+      pops.push({...cell, parentId: config.uuid})
     }
   })
 
   config.action && config.action.forEach(cell => {
     if (['pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
       action.push(cell)
+    } else if (pops && cell.OpenType === 'popview') {
+      pops.push({...cell, parentId: config.uuid})
     }
   })
 
diff --git a/src/views/imdesign/index.jsx b/src/views/imdesign/index.jsx
index 2d6eeab..47ab0c1 100644
--- a/src/views/imdesign/index.jsx
+++ b/src/views/imdesign/index.jsx
@@ -188,41 +188,39 @@
   }
 
   getAppPictures = () => {
-    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
-
-    Api.getSystemConfig({
+    if (sessionStorage.getItem('app_pictures')) return
+    
+    let deffers = []
+    let param = {
       func: 's_url_db_adduptdel',
       PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
       PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-      typecharone: 'image',
       type: 'search'
-    }).then(res => {
-      if (res.status) {
-        sessionStorage.setItem('app_pictures', JSON.stringify(res.data || []))
-      }
+    }
+    deffers = [new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'image'}).then(res => {
+          resolve(res.data)
+        })
+      }, 500)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'video'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1000)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'color'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1500)
+    })]
 
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'video',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_videos', JSON.stringify(res.data || []))
-        }
-      })
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'color',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_colors', JSON.stringify(res.data || []))
-        }
-      })
+    Promise.all(deffers).then(response => {
+      sessionStorage.setItem('app_pictures', JSON.stringify(response[0] || []))
+      sessionStorage.setItem('app_videos', JSON.stringify(response[1] || []))
+      sessionStorage.setItem('app_colors', JSON.stringify(response[2] || []))
     })
   }
 
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 510bace..0d73df8 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -4,7 +4,7 @@
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button, Typography } from 'antd'
+import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button, Typography, Spin } from 'antd'
 import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
 import html2canvas from 'html2canvas'
 import md5 from 'md5'
@@ -12,10 +12,9 @@
 import Api from '@/api'
 import options from '@/store/options.js'
 import Utils, { setGLOBFuncs } from '@/utils/utils.js'
-// import antdEnUS from 'antd/es/locale/en_US'
 import antdZhCN from 'antd/es/locale/zh_CN'
 import MKEmitter from '@/utils/events.js'
-import MenuUtils from '@/utils/utils-custom.js'
+import MenuUtils, { getTables } from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 
 import '@/assets/css/design.scss'
@@ -28,6 +27,7 @@
 
 const MenuForm = asyncComponent(() => import('./menuform'))
 const HomeForm = asyncComponent(() => import('./homeform'))
+const PopView = asyncComponent(() => import('./popview'))
 const Header = asyncComponent(() => import('@/menu/header'))
 const MenuShell = asyncComponent(() => import('@/menu/menushell'))
 const PrintMenuForm = asyncComponent(() => import('./printmenuform'))
@@ -68,7 +68,8 @@
     comloading: false,
     settingshow: true,
     eyeopen: false,
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
+    view: '',
+    popConfig: null,
   }
 
   UNSAFE_componentWillMount() {
@@ -106,7 +107,6 @@
 
   componentDidMount () {
     MKEmitter.addListener('delButtons', this.delButtons)
-    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('copyButtons', this.copyButtons)
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
@@ -145,10 +145,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -175,15 +188,10 @@
       return
     }
     MKEmitter.removeListener('delButtons', this.delButtons)
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('copyButtons', this.copyButtons)
     MKEmitter.removeListener('changePopview', this.initPopview)
     MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
     MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   triggerMenuSave = () => {
@@ -235,41 +243,39 @@
   }
 
   getAppPictures = () => {
-    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
+    if (sessionStorage.getItem('app_pictures')) return
     
-    Api.getSystemConfig({
+    let deffers = []
+    let param = {
       func: 's_url_db_adduptdel',
       PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
       PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-      typecharone: 'image',
       type: 'search'
-    }).then(res => {
-      if (res.status) {
-        sessionStorage.setItem('app_pictures', JSON.stringify(res.data || []))
-      }
+    }
+    deffers = [new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'image'}).then(res => {
+          resolve(res.data)
+        })
+      }, 500)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'video'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1000)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'color'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1500)
+    })]
 
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'video',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_videos', JSON.stringify(res.data || []))
-        }
-      })
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'color',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_colors', JSON.stringify(res.data || []))
-        }
-      })
+    Promise.all(deffers).then(response => {
+      sessionStorage.setItem('app_pictures', JSON.stringify(response[0] || []))
+      sessionStorage.setItem('app_videos', JSON.stringify(response[1] || []))
+      sessionStorage.setItem('app_colors', JSON.stringify(response[2] || []))
     })
   }
 
@@ -330,22 +336,30 @@
   }
 
   initPopview = (card, btn) => {
-    const { oriConfig, config } = this.state
-
-    if (!is(fromJS(oriConfig), fromJS(config))) {
-      notification.warning({
-        top: 92,
-        message: '閰嶇疆宸蹭慨鏀癸紝璇蜂繚瀛橈紒',
-        duration: 5
-      })
-      return
-    }
+    const { config } = this.state
 
     let _btn = fromJS(btn).toJS()
-    _btn.MenuName = config.MenuName + '-' + card.name + '-' + btn.label
-    _btn.ParentMenuID = config.uuid
 
-    this.props.history.push('/popdesign/' + window.btoa(window.encodeURIComponent((JSON.stringify(_btn)))))
+    if (_btn.config) {
+      _btn.config.uuid = _btn.uuid
+      _btn.config.MenuID = _btn.uuid
+      _btn.config.ParentId = card.uuid
+    } else {
+      _btn.config = {
+        uuid: _btn.uuid,
+        MenuID: _btn.uuid,
+        ParentId: card.uuid,
+        enabled: false,
+        MenuName: btn.label,
+        tables: config.tables || [],
+        Template: 'CustomPage',
+        components: [],
+        viewType: 'popview',
+        style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
+      }
+    }
+
+    this.setState({view: 'popview', popConfig: _btn})
   }
 
   closeView = () => {
@@ -391,7 +405,7 @@
 
         if (!config) {
           config = {
-            version: 1.0,
+            version: 2.0,
             uuid: MenuId,
             MenuID: MenuId,
             parentId: ParentId,
@@ -437,11 +451,19 @@
         config.open_edition = result.open_edition || ''
         window.GLOB.urlFields = config.urlFields || []
 
-        this.setState({
-          oriConfig: config,
-          config: fromJS(config).toJS()
-        })
-        window.GLOB.customMenu = config
+        // if (config.version !== 2.0) {
+        //   this.setState({
+        //     oriConfig: fromJS(config).toJS(),
+        //     comloading: true
+        //   })
+        //   this.updatePage(config)
+        // } else {
+          this.setState({
+            oriConfig: fromJS(config).toJS(),
+            config: config
+          })
+          window.GLOB.customMenu = config
+        // }
       } else {
         notification.warning({
           top: 92,
@@ -450,6 +472,26 @@
         })
       }
     })
+  }
+
+  updatePage = (config) => {
+    let popBtns = []
+
+    let traversal = (components) => {
+      components.forEach(item => {
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            traversal(tab.components)
+          })
+        } else if (item.type === 'group') {
+          traversal(item.components)
+        } else if (item.type !== 'search') {
+          item.$tables = getTables(item, popBtns)
+        }
+      })
+    }
+
+    traversal(config.components)
   }
 
   getMenuMessage = (delButtons, tbs) => {
@@ -1054,11 +1096,11 @@
   }
 
   render () {
-    const { activeKey, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen } = this.state
+    const { view, activeKey, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen } = this.state
 
     return (
       <ConfigProvider locale={_locale}>
-        <div className={'pc-menu-view ' + (MenuType || '')}>
+        {view !== 'popview' ? <div className={'pc-menu-view ' + (MenuType || '')}>
           <Header />
           <DndProvider backend={HTML5Backend}>
             <div className="menu-body">
@@ -1125,15 +1167,15 @@
                     <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
                   </div>
                 } style={{ width: '100%' }}>
-                  {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
+                  {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : <Spin className="loading-config" size="large" />}
                 </Card>
               </div>
             </div>
           </DndProvider>
-          <StyleController />
-          <StyleCombController />
-          <ModalController />
-        </div>
+        </div> : <PopView btn={this.state.popConfig}/>}
+        <ModalController />
+        <StyleController />
+        <StyleCombController />
       </ConfigProvider>
     )
   }
diff --git a/src/views/menudesign/index.scss b/src/views/menudesign/index.scss
index 4c68c97..bc7cde3 100644
--- a/src/views/menudesign/index.scss
+++ b/src/views/menudesign/index.scss
@@ -5,6 +5,12 @@
 .pc-menu-view {
   background: #000;
   min-height: 100vh;
+  .loading-config {
+    position: absolute;
+    left: calc(50% - 22px);
+    top: calc(50vh - 70px);
+    z-index: 10;
+  }
   .mk-hidden {
     text-decoration: line-through!important;
     span {
diff --git a/src/views/menudesign/popview/index.jsx b/src/views/menudesign/popview/index.jsx
new file mode 100644
index 0000000..cad81e4
--- /dev/null
+++ b/src/views/menudesign/popview/index.jsx
@@ -0,0 +1,283 @@
+import React, { Component } from 'react'
+import { DndProvider } from 'react-dnd'
+import { is, fromJS } from 'immutable'
+import PropTypes from 'prop-types'
+import HTML5Backend from 'react-dnd-html5-backend'
+import { notification, Modal, Collapse, Card, Switch, Button } from 'antd'
+import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
+
+import MKEmitter from '@/utils/events.js'
+import asyncComponent from '@/utils/asyncComponent'
+
+import './index.scss'
+
+const { Panel } = Collapse
+const { confirm } = Modal
+
+const MenuForm = asyncComponent(() => import('./menuform'))
+const Header = asyncComponent(() => import('@/menu/header'))
+const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
+const Modulecell = asyncComponent(() => import('@/menu/modulecell'))
+const MenuShell = asyncComponent(() => import('@/menu/menushell'))
+const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
+const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
+const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
+const StyleCombControlButton = asyncComponent(() => import('@/menu/stylecombcontrolbutton'))
+const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
+
+class PopViewDesign extends Component {
+  static propTpyes = {
+    btn: PropTypes.object,
+    updateConfig: PropTypes.func
+  }
+
+  state = {
+    MenuId: '',
+    activeKey: 'basedata',
+    menuloading: false,
+    oriConfig: null,
+    config: null,
+    comloading: false,
+    eyeopen: false
+  }
+
+  UNSAFE_componentWillMount() {
+    const { btn } = this.props
+    sessionStorage.setItem('editMenuType', 'popview')
+
+    let config = fromJS(btn.config).toJS()
+
+    window.GLOB.urlFields = []               // url鍙橀噺
+    window.GLOB.customMenu = config          // 淇濆瓨鑿滃崟淇℃伅
+
+    this.setState({config: config, oriConfig: fromJS(config).toJS()})
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('triggerMenuSave', this.submitConfig)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('triggerMenuSave', this.submitConfig)
+  }
+
+  closeView = () => {
+    const { oriConfig, config } = this.state
+
+    if (!is(fromJS(oriConfig), fromJS(config))) {
+      confirm({
+        title: '閰嶇疆宸蹭慨鏀癸紝鏀惧純淇濆瓨鍚楋紵',
+        content: '',
+        onOk() {
+          // window.history.back()
+        },
+        onCancel() {}
+      })
+    } else {
+      // window.history.back()
+    }
+  }
+
+  getMenuMessage = (tbs) => {
+    const { config } = this.state
+
+    let traversal = (components) => {
+      components.forEach(item => {
+        if (item.$tables) {
+          tbs.push(...item.$tables)
+        }
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            traversal(tab.components)
+          })
+        } else if (item.type === 'group') {
+          traversal(item.components)
+        }
+      })
+    }
+
+    traversal(config.components)
+  }
+
+  submitConfig = () => {
+    let config = fromJS(this.state.config).toJS()
+
+    if (config.cacheUseful === 'true' && !config.cacheTime) {
+      notification.warning({
+        top: 92,
+        message: '璇峰畬鍠勭紦瀛樿缃紒',
+        duration: 5
+      })
+      return
+    }
+
+    if (config.enabled && this.verifyConfig()) {
+      config.enabled = false
+    }
+
+    this.setState({
+      menuloading: true
+    })
+  }
+
+  onEnabledChange = () => {
+    const { config } = this.state
+
+    if (!config.enabled && this.verifyConfig(true)) {
+      return
+    }
+
+    this.setState({
+      config: {...config, enabled: !config.enabled}
+    })
+  }
+
+  verifyConfig = (show) => {
+    const { config } = this.state
+    let error = ''
+
+    let check = (components) => {
+      components.forEach(item => {
+        if (error) return
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            check(tab.components)
+          })
+          return
+        } else if (item.type === 'group') {
+          check(item.components)
+          return
+        } else if (!item.errors || item.errors.length === 0) {
+          return
+        }
+        
+        item.errors.forEach(err => {
+          if (err.level !== 0 || error) return
+          error = `缁勪欢銆�${item.name}銆�${err.detail}`
+        })
+      })
+    }
+
+    check(config.components)
+
+    if (show && error) {
+      notification.warning({
+        top: 92,
+        message: error,
+        duration: 5
+      })
+    }
+
+    return error
+  }
+
+  // 鏇存柊閰嶇疆淇℃伅
+  updateConfig = (config) => {
+    this.setState({
+      config: config
+    })
+
+    window.GLOB.customMenu = config
+  }
+
+  resetConfig = (config) => {
+    this.setState({
+      config,
+      comloading: true
+    }, () => {
+      this.setState({
+        comloading: false
+      })
+    })
+
+    window.GLOB.customMenu = config
+  }
+
+  /**
+   * @description 鏇存柊甯哥敤琛ㄤ俊鎭紝蹇嵎娣诲姞鍚庢洿鏂伴厤缃俊鎭�
+   */
+  updatetable = (config) => {
+    this.setState({ config })
+
+    window.GLOB.customMenu = config
+  }
+
+  insert = (item) => {
+    let config = fromJS(this.state.config).toJS()
+
+    config.components.push(item)
+
+    this.setState({config})
+    window.GLOB.customMenu = config
+    
+    notification.success({
+      top: 92,
+      message: '绮樿创鎴愬姛锛�',
+      duration: 2
+    })
+  }
+
+  render () {
+    const { activeKey, comloading, config, menuloading, eyeopen } = this.state
+
+    return (
+      <div className="pc-poper-view">
+        <Header />
+        <DndProvider backend={HTML5Backend}>
+          <div className="menu-body">
+            <div className="menu-setting">
+              <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
+                {/* 鍩烘湰淇℃伅 */}
+                <Panel header="鍩烘湰淇℃伅" key="basedata">
+                  {/* 鑿滃崟淇℃伅 */}
+                  <MenuForm config={config} updateConfig={this.updateConfig}/>
+                  {/* 琛ㄥ悕娣诲姞 */}
+                  <TableComponent config={config} updatetable={this.updatetable}/>
+                </Panel>
+                {/* 缁勪欢娣诲姞 */}
+                <Panel header="缁勪欢" key="component">
+                  <SourceWrap MenuType="" />
+                </Panel>
+                <Panel header="鍏冪礌" key="element">
+                  <Modulecell />
+                </Panel>
+                <Panel header="椤甸潰鏍峰紡" key="background">
+                  <BgController config={config} updateConfig={this.updateConfig} />
+                </Panel>
+              </Collapse>
+            </div>
+            <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
+              <Card title={
+                <div> {config.MenuName} </div>
+              } bordered={false} extra={
+                <div>
+                  <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
+                  <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
+                  <StyleCombControlButton menu={config} />
+                  <PasteController insert={this.insert} />
+                  <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} />
+                  <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
+                  <Button type="default" onClick={this.closeView}>杩斿洖</Button>
+                </div>
+              } style={{ width: '100%' }}>
+                {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
+              </Card>
+            </div>
+          </div>
+        </DndProvider>
+      </div>
+    )
+  }
+}
+
+export default PopViewDesign
\ No newline at end of file
diff --git a/src/views/menudesign/popview/index.scss b/src/views/menudesign/popview/index.scss
new file mode 100644
index 0000000..2d06a62
--- /dev/null
+++ b/src/views/menudesign/popview/index.scss
@@ -0,0 +1,174 @@
+.pc-poper-view {
+  background: #000;
+  min-height: 100vh;
+
+  .eye-open {
+    .component-name {
+      display: block;
+    }
+    .anticon-tool {
+      display: none;
+    }
+  }
+
+  .component-name {
+    position: absolute;
+    z-index: 9;
+    display: none;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    background: rgba(255, 255, 255, 0.9);
+    border: 1px solid #1890ff;
+    .center {
+      position: absolute;
+      font-size: 16px;
+      left: 50%;
+      top: 50%;
+      color: #1890ff;
+      transform: translate(-50%, -50%);
+      max-width: 70%;
+      .title {
+        text-align: center;
+      }
+    }
+    .error {
+      text-align: center;
+      color: red;
+      display: block;
+    }
+    .waring {
+      color: orange;
+    }
+  }
+  
+  >.menu-body {
+    width: 100vw;
+    height: 100vh;
+    overflow-x: hidden;
+    position: relative;
+    background: #ffffff;
+    padding: 50px 0px 0px 0px;
+
+    .menu-setting {
+      position: fixed;
+      left: 0;
+      top: 48px;
+      z-index: 10;
+      height: calc(100vh - 48px);
+      width: 300px;
+      background: #ffffff;
+      box-shadow: 0px 2px 5px #bcbcbc;
+      overflow-y: auto;
+      overflow-x: hidden;
+
+      > .ant-collapse {
+        background-color: #ffffff;
+        .ant-collapse-item.ant-collapse-item-active {
+          border-bottom: 1px solid #d9d9d9;
+        }
+        .ant-collapse-header {
+          padding: 11px 16px 10px 40px;
+          border-bottom: 1px solid #d9d9d9;
+          background: #1890ff;
+          color: #ffffff;
+        }
+        .ant-collapse-content-box {
+          .ant-form-item {
+            margin-bottom: 10px;
+          }
+        }
+      }
+
+      >.ant-tabs {
+        >.ant-tabs-bar {
+          border-bottom: 1px solid #181F29;
+          margin-bottom: 0px;
+          min-height: 48px;
+          .ant-tabs-tab {
+            padding: 14px 16px;
+            color: rgba(255, 255, 255, 0.85);
+          }
+          .ant-tabs-tab-active.ant-tabs-tab {
+            color: #1890ff;
+          }
+        }
+      }
+    }
+    .menu-setting::-webkit-scrollbar {
+      width: 4px;
+    }
+    .menu-setting::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08);
+      background: rgba(0, 0, 0, 0.08);
+    }
+    .menu-setting::-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);
+    }
+
+    .menu-view {
+      position: relative;
+      width: calc(100vw - 300px);
+      margin-left: 300px;
+      height: calc(100vh - 50px);
+      overflow-y: auto;
+
+      > .ant-card {
+        >.ant-card-head {
+          margin-bottom: 0px;
+          position: relative;
+          .ant-card-head-title {
+            color: #1890ff;
+            padding: 5px 0;
+          }
+          .ant-card-extra {
+            padding: 5px 0;
+            button {
+              margin-left: 20px;
+            }
+            .ant-switch.big {
+              min-width: 60px;
+              height: 28px;
+              line-height: 28px;
+              margin-top: -2px;
+              .ant-switch-inner {
+                font-size: 14px;
+              }
+            }
+            .ant-switch.big:after {
+              width: 24px;
+              height: 24px;
+            }
+          }
+        }
+        >.ant-card-body {
+          padding: 0px;
+        }
+      }
+    }
+    .menu-view.saving {
+      .anticon-tool {
+        display: none;
+      }
+    }
+    .menu-view::-webkit-scrollbar {
+      width: 7px;
+    }
+    .menu-view::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08);
+      background: rgba(0, 0, 0, 0.08);
+    }
+    .menu-view::-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);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/views/menudesign/popview/menuform/index.jsx b/src/views/menudesign/popview/menuform/index.jsx
new file mode 100644
index 0000000..a925865
--- /dev/null
+++ b/src/views/menudesign/popview/menuform/index.jsx
@@ -0,0 +1,98 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Radio, Tooltip, InputNumber } from 'antd'
+import { QuestionCircleOutlined } from '@ant-design/icons'
+
+// import './index.scss'
+
+class CustomMenuForm extends Component {
+  static propTpyes = {
+    config: PropTypes.object,
+    updateConfig: PropTypes.func
+  }
+  
+  changeCacheDay = (val) => {
+    if (typeof(val) !== 'number') {
+      val = ''
+    }
+    this.props.updateConfig({...this.props.config, cacheTime: val})
+  }
+
+  selectChange = (key, value) => {
+    const { config } = this.props
+
+    if (key === 'cacheUseful') {
+      this.props.updateConfig({...config, cacheUseful: value})
+    } else if (key === 'timeUnit') {
+      this.props.updateConfig({...config, timeUnit: value})
+    }
+  }
+
+  render() {
+    const { config } = this.props
+    const { getFieldDecorator } = this.props.form
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <Form {...formItemLayout}>
+        <Row>
+          <Col span={24}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="瀵逛簬涓嶇粡甯告�у彉鍔ㄧ殑淇℃伅锛岀紦瀛樻暟鎹湁鍔╀簬鎻愰珮鏌ヨ鏁堢巼銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                缂撳瓨鏁版嵁
+              </Tooltip>
+            }>
+              {getFieldDecorator('cacheUseful', {
+                initialValue: config.cacheUseful || 'false'
+              })(
+                <Radio.Group onChange={(e) => {this.selectChange('cacheUseful', e.target.value)}}>
+                  <Radio value="true">浣跨敤</Radio>
+                  <Radio value="false">涓嶄娇鐢�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {config.cacheUseful === 'true' ? <Col span={24}>
+            <Form.Item label="鍗曚綅">
+              {getFieldDecorator('timeUnit', {
+                initialValue: config.timeUnit || 'day'
+              })(
+                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                  <Radio value="day">澶�</Radio>
+                  <Radio value="hour">灏忔椂</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
+          {config.cacheUseful === 'true' ? <Col span={24}>
+            <Form.Item label="鏃堕暱">
+              {getFieldDecorator('cacheTime', {
+                initialValue: config.cacheTime,
+                rules: [
+                  {
+                    required: true,
+                    message: '璇疯緭鍏ユ椂闀�!'
+                  }
+                ]
+              })(
+                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
+              )}
+            </Form.Item>
+          </Col> : null}
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(CustomMenuForm)
\ No newline at end of file
diff --git a/src/views/menudesign/popview/menuform/index.scss b/src/views/menudesign/popview/menuform/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/views/menudesign/popview/menuform/index.scss
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index bbd3cdb..f615787 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -76,7 +76,6 @@
     adapters: [],
     viewType: 'menu',
     eyeopen: false,
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   UNSAFE_componentWillMount() {
@@ -149,7 +148,6 @@
       document.getElementById('mk-mob-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">鏈簲鐢ㄦ病鏈塒C绔〉闈㈢殑缂栬緫鏉冮檺锛岃鑱旂郴绠$悊鍛橈紒</div>'
       return
     }
-    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('triggerMenuSave', this.submitConfig)
     MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
     MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
@@ -187,10 +185,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -216,14 +227,9 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('triggerMenuSave', this.submitConfig)
     MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
     MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   getSmStemp = () => {
@@ -369,41 +375,39 @@
   }
 
   getAppPictures = () => {
-    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
-
-    Api.getSystemConfig({
+    if (sessionStorage.getItem('app_pictures')) return
+    
+    let deffers = []
+    let param = {
       func: 's_url_db_adduptdel',
       PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
       PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-      typecharone: 'image',
       type: 'search'
-    }).then(res => {
-      if (res.status) {
-        sessionStorage.setItem('app_pictures', JSON.stringify(res.data || []))
-      }
+    }
+    deffers = [new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'image'}).then(res => {
+          resolve(res.data)
+        })
+      }, 500)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'video'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1000)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'color'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1500)
+    })]
 
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'video',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_videos', JSON.stringify(res.data || []))
-        }
-      })
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'color',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_colors', JSON.stringify(res.data || []))
-        }
-      })
+    Promise.all(deffers).then(response => {
+      sessionStorage.setItem('app_pictures', JSON.stringify(response[0] || []))
+      sessionStorage.setItem('app_videos', JSON.stringify(response[1] || []))
+      sessionStorage.setItem('app_colors', JSON.stringify(response[2] || []))
     })
   }
 
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index f3a98e3..24039b6 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -70,7 +70,6 @@
     controlshow: sessionStorage.getItem('controlshow') !== 'false',
     comloading: false,
     eyeopen: false,
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   UNSAFE_componentWillMount() {
@@ -127,7 +126,6 @@
       return
     }
     MKEmitter.addListener('delButtons', this.delButtons)
-    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('copyButtons', this.copyButtons)
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
@@ -167,10 +165,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -200,16 +211,11 @@
       return
     }
     MKEmitter.removeListener('delButtons', this.delButtons)
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('copyButtons', this.copyButtons)
     MKEmitter.removeListener('changePopview', this.initPopview)
     MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
     MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
     MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   triggerMenuSave = () => {
@@ -396,59 +402,39 @@
   }
 
   getAppPictures = () => {
-    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
-
-    Api.getSystemConfig({
+    if (sessionStorage.getItem('app_pictures')) return
+    
+    let deffers = []
+    let param = {
       func: 's_url_db_adduptdel',
       PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
       PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-      typecharone: 'image',
       type: 'search'
-    }).then(res => {
-      if (res.status) {
-        sessionStorage.setItem('app_pictures', JSON.stringify(res.data || []))
-      } else if (!res.status) {
-        notification.warning({
-          top: 92,
-          message: res.message,
-          duration: 5
+    }
+    deffers = [new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'image'}).then(res => {
+          resolve(res.data)
         })
-      }
+      }, 500)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'video'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1000)
+    }), new Promise(resolve => {
+      setTimeout(() => {
+        Api.getSystemConfig({...param, typecharone: 'color'}).then(res => {
+          resolve(res.data)
+        })
+      }, 1500)
+    })]
 
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'video',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_videos', JSON.stringify(res.data || []))
-        } else if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'color',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_colors', JSON.stringify(res.data || []))
-        } else if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
+    Promise.all(deffers).then(response => {
+      sessionStorage.setItem('app_pictures', JSON.stringify(response[0] || []))
+      sessionStorage.setItem('app_videos', JSON.stringify(response[1] || []))
+      sessionStorage.setItem('app_colors', JSON.stringify(response[2] || []))
     })
   }
 
diff --git a/src/views/popdesign/index.jsx b/src/views/popdesign/index.jsx
index ee36fc4..f95c418 100644
--- a/src/views/popdesign/index.jsx
+++ b/src/views/popdesign/index.jsx
@@ -115,10 +115,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index f57afa6..c834d07 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -52,10 +52,8 @@
     menuloading: false,
     oriConfig: null,
     config: null,
-    customComponents: [],
     comloading: false,
     settingshow: true,
-    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   UNSAFE_componentWillMount() {
@@ -91,20 +89,9 @@
   }
 
   componentDidMount () {
-    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
-    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
     setTimeout(() => {
-      if (sessionStorage.getItem('app_custom_components')) {
-        let list = sessionStorage.getItem('app_custom_components')
-        list = JSON.parse(list)
-
-        this.setCustomComponent(list)
-      } else {
-        this.updateCustomComponent()
-      }
-      this.getAppPictures()
       this.getPrintTemp()
       this.getRoleFields()
       setGLOBFuncs()
@@ -129,10 +116,23 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
-        if (this.state.modalStatus) {
+        let modals = document.querySelectorAll('.mk-pop-modal')
+        let msg = null
+        for (let i = 0; i < modals.length; i++) {
+          if (msg) {
+            break
+          }
+
+          let node = modals[i].querySelector('.mk-com-name')
+
+          if (node) {
+            msg = node.innerText
+          }
+        }
+        if (msg) {
           notification.warning({
             top: 92,
-            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            message: '璇蜂繚瀛�' + msg,
             duration: 5
           })
           return false
@@ -158,14 +158,8 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('changePopview', this.initPopview)
     MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
-    MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
-  }
-
-  modalStatus = (val) => {
-    this.setState({modalStatus: val})
   }
 
   triggerMenuSave = () => {
@@ -214,93 +208,6 @@
         }
       })
     }
-  }
-
-  getAppPictures = () => {
-    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
-    
-    Api.getSystemConfig({
-      func: 's_url_db_adduptdel',
-      PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-      PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-      typecharone: 'image',
-      type: 'search'
-    }).then(res => {
-      if (res.status) {
-        sessionStorage.setItem('app_pictures', JSON.stringify(res.data || []))
-      }
-
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'video',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_videos', JSON.stringify(res.data || []))
-        }
-      })
-      Api.getSystemConfig({
-        func: 's_url_db_adduptdel',
-        PageIndex: 0,  // 0 浠h〃鍏ㄩ儴
-        PageSize: 0,   // 0 浠h〃鍏ㄩ儴
-        typecharone: 'color',
-        type: 'search'
-      }).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('app_colors', JSON.stringify(res.data || []))
-        }
-      })
-    })
-  }
-
-  updateCustomComponent = () => {
-    Api.getSystemConfig({
-      func: 's_get_custom_components',
-      typename: '',
-      typecharone: ''
-    }).then(res => {
-      if (!res.status) {
-        notification.warning({
-          top: 92,
-          message: res.message,
-          duration: 5
-        })
-      } else if (res.cus_list) {
-        sessionStorage.setItem('app_custom_components', JSON.stringify(res.cus_list))
-        this.setCustomComponent(res.cus_list)
-      }
-    })
-  }
-
-  setCustomComponent = (cus_list) => {
-    let coms = []
-
-    cus_list.forEach(item => {
-      let config = ''
-
-      try {
-        config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
-      } catch (e) {
-        console.warn('Parse Failure')
-        config = ''
-      }
-
-      if (!config || !item.c_name) return
-
-      window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
-      coms.push({
-        uuid: item.c_id,
-        type: 'menu',
-        title: item.c_name,
-        url: item.images,
-        component: config.type,
-        subtype: config.subtype,
-        config
-      })
-    })
-    this.setState({customComponents: coms})
   }
 
   initPopview = (card, btn) => {
@@ -424,7 +331,7 @@
     })
   }
 
-  getMenuMessage = (delButtons, tbs) => {
+  getMenuMessage = (tbs) => {
     const { config } = this.state
     let buttons = []
     let _sort = 1
@@ -435,23 +342,27 @@
           if (tab.components[0].$tables) {
             tbs.push(...tab.components[0].$tables)
           }
+
+          if (tab.permission !== 'true' || tab.hide === 'true') return
+
+          buttons.push(`select '${tab.components[0].uuid}' as menuid, '${tab.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
+          _sort++
+
+          let _s = 1
+
           tab.components[0].action.forEach(btn => {
-            if (btn.hidden === 'true') {
-              delButtons.push(btn.uuid)
-              return
-            }
-            buttons.push(`select '${btn.uuid}' as menuid, '${tab.label + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
-            _sort++
+            if (btn.hidden === 'true') return
+
+            buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_s * 10}' as Sort, '${tab.components[0].uuid}' as parentid, 60 as Type`)
+            _s++
           })
           tab.components[0].cols.forEach(col => {
             if (col.type !== 'action') return
             col.elements.forEach(btn => {
-              if (btn.hidden === 'true') {
-                delButtons.push(btn.uuid)
-                return
-              }
-              buttons.push(`select '${btn.uuid}' as menuid, '${tab.label + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
-              _sort++
+              if (btn.hidden === 'true') return
+
+              buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_s * 10}' as Sort, '${tab.components[0].uuid}' as parentid, 60 as Type`)
+              _s++
             })
           })
         })
@@ -460,21 +371,17 @@
           tbs.push(...item.$tables)
         }
         item.action.forEach(btn => {
-          if (btn.hidden === 'true') {
-            delButtons.push(btn.uuid)
-            return
-          }
-          buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_sort * 10}' as Sort`)
+          if (btn.hidden === 'true') return
+
+          buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
           _sort++
         })
         item.cols.forEach(col => {
           if (col.type !== 'action') return
           col.elements.forEach(btn => {
-            if (btn.hidden === 'true') {
-              delButtons.push(btn.uuid)
-              return
-            }
-            buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_sort * 10}' as Sort`)
+            if (btn.hidden === 'true') return
+
+            buttons.push(`select '${btn.uuid}' as menuid,  '${btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
             _sort++
           })
         })
@@ -506,8 +413,7 @@
       }
 
       let tbs = []
-      let delButtons = []
-      let btns = this.getMenuMessage(delButtons, tbs)
+      let btns = this.getMenuMessage(tbs)
       let arr = []
       tbs = tbs.filter(tb => {
         let _tb = tb.toLowerCase()
@@ -567,100 +473,54 @@
         ParentID: config.uuid,
         MenuNo: config.MenuNo,
         Template: 'BaseTable',
-        PageParam: '',
-        LongParam: '',
-        LText: []
+        button_proc_edition: 'Y'
       }
 
-      btnParam.LText = btns
-      btnParam.LText = btnParam.LText.join(' union all ')
+      btnParam.LText = btns.join(' union all ')
 
       btnParam.LText = Utils.formatOptions(btnParam.LText)
       btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp)
 
       new Promise(resolve => {
-        resolve(true)
-      }).then(res => { // 鎸夐挳鍒犻櫎
-        if (delButtons.length === 0) {
-          return {
-            status: true
-          }
-        } else {
-          let _param = {
-            func: 'sPC_MainMenu_Del',
-            MenuID: delButtons.join(',')
-          }
-          return Api.getSystemConfig(_param)
-        }
-      }).then(res => { // 椤甸潰淇濆瓨
-        if (!res) return
-
-        if (res.status) {
-          return Api.getSystemConfig(param)
-        } else {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-          return false
-        }
-      }).then(res => { // 椤甸潰鎸夐挳鍏崇郴淇濆瓨
-        if (!res) return
-
-        if (res.status) {
-          let ori = this.state.oriConfig
-          if (config.MenuName !== ori.MenuName || config.MenuNo !== ori.MenuNo || config.parentId !== ori.parentId) {
-            localStorage.setItem('menuUpdate', new Date().getTime())
-          }
-          config.open_edition = res.open_edition || ''
-          this.setState({
-            config,
-            oriConfig: fromJS(config).toJS(),
-          })
-
-          if (btnParam.LText) {
-            return Api.getSystemConfig(btnParam)
-          } else {
-            return {
-              status: true
-            }
-          }
-        } else {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-          return false
-        }
-      }).then(res => { // 鎸夐挳澶嶅埗
-        if (!res) return
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-          return false
-        }
+        Api.getSystemConfig(param).then(res => {
+          resolve(res)
+        })
       }).then(res => {
-        if (res && res.status) {
-          this.setState({
-            menuloading: false
-          })
+        if (!res || !res.status) return res
+
+        let ori = this.state.oriConfig
+        if (config.MenuName !== ori.MenuName || config.MenuNo !== ori.MenuNo || config.parentId !== ori.parentId) {
+          localStorage.setItem('menuUpdate', new Date().getTime())
+        }
+        config.open_edition = res.open_edition || ''
+        this.setState({
+          config,
+          oriConfig: fromJS(config).toJS(),
+        })
+
+        return Api.getSystemConfig(btnParam)
+      }).then(res => {
+        this.setState({
+          menuloading: false
+        })
+
+        if (!res) return
+
+        if (res.status) {
           notification.success({
             top: 92,
             message: '淇濆瓨鎴愬姛',
             duration: 2
           })
+          MKEmitter.emit('completeSave')
         } else {
-          this.setState({
-            menuloading: false
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
           })
         }
-        MKEmitter.emit('completeSave')
       })
     }, 300 + (+sessionStorage.getItem('mkDelay')))
   }
diff --git a/src/views/tabledesign/index.scss b/src/views/tabledesign/index.scss
index c022ade..59d5206 100644
--- a/src/views/tabledesign/index.scss
+++ b/src/views/tabledesign/index.scss
@@ -2,6 +2,14 @@
   overflow-x: hidden;
   overflow-y: hidden;
 }
+.mk-source-wrap {
+  .ant-radio-button-wrapper:last-child {
+    display: none;
+  }
+  .ant-radio-button-wrapper:not(:first-child) {
+    border-radius: 0 4px 4px 0;
+  }
+}
 .pc-table-view {
   background: #000;
   min-height: 100vh;
@@ -17,37 +25,6 @@
     }
     .anticon-tool {
       display: none;
-    }
-  }
-  .component-name {
-    position: absolute;
-    z-index: 9;
-    display: none;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    background: rgba(255, 255, 255, 0.9);
-    border: 1px solid #1890ff;
-    .center {
-      position: absolute;
-      font-size: 16px;
-      left: 50%;
-      top: 50%;
-      color: #1890ff;
-      transform: translate(-50%, -50%);
-      max-width: 70%;
-      .title {
-        text-align: center;
-      }
-    }
-    .error {
-      text-align: center;
-      color: red;
-      display: block;
-    }
-    .waring {
-      color: orange;
     }
   }
   >.menu-body {
@@ -137,7 +114,7 @@
     }
 
     .menu-setting.hidden {
-      left: -300px;
+      left: -280px;
     }
     .menu-setting.hidden + .menu-view {
       width: 100vw;
diff --git a/src/views/tabledesign/source.jsx b/src/views/tabledesign/source.jsx
index eb8691e..d4d1666 100644
--- a/src/views/tabledesign/source.jsx
+++ b/src/views/tabledesign/source.jsx
@@ -140,6 +140,12 @@
     },
     {
       type: 'col',
+      label: '瑙嗛',
+      subType: 'video',
+      $init: true
+    },
+    {
+      type: 'col',
       label: '閾炬帴',
       subType: 'link',
       $init: true

--
Gitblit v1.8.0