From 59db6fab9c1ed1fa5559d423d439e14ea33b1598 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 27 四月 2023 11:18:24 +0800
Subject: [PATCH] Merge branch 'develop'

---
 src/templates/zshare/modalform/index.jsx                               |    8 
 src/menu/components/timeline/normal-timeline/index.jsx                 |   42 
 src/menu/components/card/table-card/index.jsx                          |   60 -
 src/menu/components/share/markcomponent/index.jsx                      |    9 
 src/templates/zshare/codemirror/replaceform/index.jsx                  |   24 
 src/utils/utils-custom.js                                              |  178 ++++
 src/views/main/index.jsx                                               |   14 
 src/views/design/header/editfirstmenu/index.jsx                        |    1 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                 |    6 
 src/menu/datasource/index.jsx                                          |    6 
 src/menu/components/module/voucher/index.jsx                           |    4 
 src/menu/components/chart/antv-scatter/index.jsx                       |   34 
 src/menu/components/table/edit-table/options.jsx                       |   12 
 src/menu/components/tree/antd-tree/index.jsx                           |   31 
 src/views/billprint/index.jsx                                          |   57 +
 src/mob/modalconfig/index.jsx                                          |    8 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                  |    6 
 src/components/header/loginform.jsx                                    |   18 
 src/menu/components/table/edit-table/columns/editColumn/index.jsx      |    6 
 src/views/design/sidemenu/editthdmenu/index.jsx                        |    1 
 src/views/mobdesign/index.jsx                                          |   35 
 src/views/menudesign/index.jsx                                         |   38 
 src/menu/datasource/verifycard/index.jsx                               |   15 
 src/tabviews/custom/components/card/data-card/index.jsx                |    1 
 src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx |   18 
 src/tabviews/custom/components/module/voucher/index.jsx                |   45 
 src/views/design/sidemenu/editsecmenu/index.jsx                        |    1 
 src/templates/zshare/modalform/datatable/index.jsx                     |    6 
 src/menu/components/form/tab-form/index.jsx                            |   20 
 src/menu/components/share/actioncomponent/formconfig.jsx               |    3 
 src/tabviews/custom/components/group/normal-group/index.jsx            |  158 +-
 src/menu/components/carousel/prop-card/index.jsx                       |   71 -
 src/menu/components/card/double-data-card/index.jsx                    |   87 -
 src/router/index.js                                                    |   71 -
 src/menu/components/group/normal-group/options.jsx                     |  112 +-
 src/menu/components/card/data-card/index.jsx                           |   91 -
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx  |   25 
 src/menu/components/chart/antv-pie/index.jsx                           |   34 
 src/tabviews/zshare/mutilform/index.jsx                                |   13 
 src/menu/components/chart/antv-dashboard/index.jsx                     |   26 
 src/tabviews/custom/index.jsx                                          |   77 +
 src/menu/components/card/prop-card/index.jsx                           |  137 ---
 src/menu/components/table/normal-table/index.jsx                       |   74 -
 src/menu/components/table/normal-table/columns/index.jsx               |    5 
 src/menu/components/group/normal-group/index.jsx                       |    6 
 src/menu/components/table/edit-table/columns/index.jsx                 |    3 
 src/menu/modalconfig/controller.jsx                                    |    2 
 src/menu/components/module/voucher/voucherTable/index.scss             |    2 
 src/views/menudesign/popview/index.jsx                                 |   33 
 src/menu/components/chart/antv-G6/index.jsx                            |   31 
 src/tabviews/custom/components/module/account/index.jsx                |   23 
 src/components/header/index.jsx                                        |    6 
 src/tabviews/custom/components/card/double-data-card/index.jsx         |    1 
 src/menu/components/chart/chart-custom/index.jsx                       |   18 
 src/menu/components/iframe/index.jsx                                   |   19 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                |    4 
 src/menu/components/form/simple-form/index.jsx                         |   22 
 src/menu/components/chart/antv-bar/index.jsx                           |   43 
 src/menu/components/code/sandbox/index.jsx                             |   17 
 src/tabviews/custom/components/table/edit-table/index.jsx              |    9 
 src/views/tabledesign/index.jsx                                        |   35 
 src/api/index.js                                                       |    4 
 src/tabviews/custom/components/share/normalTable/index.jsx             |    6 
 src/templates/modalconfig/dragelement/index.jsx                        |    2 
 src/menu/components/table/edit-table/index.jsx                         |   66 -
 src/templates/zshare/codemirror/index.jsx                              |    3 
 src/menu/components/carousel/data-card/index.jsx                       |   43 
 src/menu/sysinterface/index.jsx                                        |    6 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx  |    2 
 src/mob/components/search/single-search/index.jsx                      |    2 
 src/menu/components/card/balcony/index.jsx                             |   64 -
 src/menu/components/module/voucher/options.jsx                         |   21 
 src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx     |    2 
 src/menu/components/share/pastecomponent/index.jsx                     |    9 
 src/menu/components/form/step-form/index.jsx                           |   22 
 src/menu/components/share/actioncomponent/index.scss                   |    3 
 src/views/pcdesign/index.jsx                                           |   35 
 src/templates/zshare/formconfig.jsx                                    |   12 
 src/menu/datasource/verifycard/settingform/index.jsx                   |   17 
 src/tabviews/custom/components/module/voucher/voucherTable/index.scss  |    2 
 src/tabviews/custom/components/interfaces/interItem/index.jsx          |   31 
 src/views/mobdesign/popview/index.jsx                                  |   33 
 src/mob/components/formdragelement/index.jsx                           |    2 
 src/menu/components/share/actioncomponent/index.jsx                    |   46 
 src/tabviews/zshare/actionList/printbutton/index.jsx                   |    7 
 src/menu/components/search/main-search/index.jsx                       |    2 
 src/pc/components/login/normal-login/index.jsx                         |    2 
 src/tabviews/custom/components/table/edit-table/normalTable/index.scss |    1 
 src/tabviews/custom/components/module/voucher/voucherTable/index.jsx   |    4 
 src/tabviews/custom/components/module/voucher/index.scss               |   11 
 src/menu/components/editor/braft-editor/index.jsx                      |   17 
 src/menu/modalconfig/index.jsx                                         |    8 
 src/menu/components/module/voucher/index.scss                          |   10 
 src/menu/components/table/base-table/index.jsx                         |   74 -
 src/menu/components/share/markcomponent/markform/index.jsx             |    9 
 95 files changed, 1,227 insertions(+), 1,313 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index a4dd5b9..5936c99 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -751,7 +751,7 @@
       token = JSON.parse(window.decodeURIComponent(window.atob(token)))
     } catch (e) {
       token = null
-      _resolve({status: false, ErrCode: 'E', message: '鎺ュ彛淇℃伅瑙f瀽澶辫触锛�'})
+      _resolve({status: false, ErrCode: 'E', message: '鎺ュ彛淇℃伅瑙f瀽澶辫触锛�', ErrMesg: 'token_error'})
     }
 
     if (!token) return
@@ -854,7 +854,7 @@
     param.appkey = window.GLOB.appkey || ''
 
     if (param.$token === '') {
-      return Promise.resolve({status: false, ErrCode: 'E', message: '鎺ュ彛鍦板潃灏氭湭璁剧疆锛�'})
+      return Promise.resolve({status: false, ErrCode: 'E', message: '鎺ュ彛鍦板潃灏氭湭璁剧疆锛�', ErrMesg: 'token_error'})
     } else if (param.$token) {
       return new Promise(resolve => this.visitOuterSystem(param, resolve))
     }
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 94e445b..a58854f 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -439,12 +439,6 @@
     setTimeout(() => {
       Api.getAppVersion()
     }, 1000)
-    // Api.genericInterface({
-    //   func: 's_get_fcc_account_data',
-    //   fcc_date: '2022-03-01',
-    //   search_type: ''
-    // }).then(res => {
-    // })
 
     // sessionStorage 璺ㄩ〉闈㈠叡浜�
     window.addEventListener('storage', (e) => {
diff --git a/src/components/header/loginform.jsx b/src/components/header/loginform.jsx
index 899741a..45a57c0 100644
--- a/src/components/header/loginform.jsx
+++ b/src/components/header/loginform.jsx
@@ -17,6 +17,7 @@
     remember: false,
     username: '',
     password: '',
+    oripassword: '',
     delay: +sessionStorage.getItem('mkDelay')
   }
 
@@ -38,18 +39,25 @@
       localStorage.removeItem(_url)
     }
 
-    this.setState({
-      remember: _user ? true : false,
-      username: _user ? _user.username : '',
-      password: _user ? _user.password : ''
-    })
+    if (_user) {
+      this.setState({
+        remember: true,
+        username: _user.username,
+        password: '*********',
+        oripassword: _user.password
+      })
+    }
   }
 
   handleConfirm = () => {
+    const { oripassword } = this.state
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
+          if (oripassword && values.password === '*********') {
+            values.password = oripassword
+          }
           resolve(values)
         } else {
           reject(err)
diff --git a/src/menu/components/card/balcony/index.jsx b/src/menu/components/card/balcony/index.jsx
index 9edccef..9d29317 100644
--- a/src/menu/components/card/balcony/index.jsx
+++ b/src/menu/components/card/balcony/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -126,61 +126,15 @@
       return
     }
 
-    card.errors = []
+    card.$c_ds = card.wrap.datatype === 'dynamic'
+    card.$c_ac = false
+    card.$c_sc = false
+    card.$c_el = true
+    
+    card.errors = checkComponent(card)
 
-    if (card.wrap.datatype === 'static') {
-      card.elements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
+    if (card.errors.length === 0) {
       card.$tables = getTables(card)
-    } else {
-      let columns = card.columns.map(c => c.field)
-
-      if (card.wrap.datatype === 'dynamic') {
-        if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-          card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-        } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-          card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-        } else if (!card.setting.primaryKey) {
-          card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-        } else if (!columns.includes(card.setting.primaryKey)) {
-          card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-        }
-      }
-
-      if (card.errors.length === 0) {
-        card.$tables = getTables(card)
-      }
-
-      card.elements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
     }
 
     this.setState({
@@ -333,7 +287,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 03d50c4..56600cb 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -162,8 +162,6 @@
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
   updateComponent = (card) => {
-    const { appType } = this.state
-
     card.width = card.wrap.width
     card.name = card.wrap.name
 
@@ -176,86 +174,15 @@
       return
     }
 
-    card.errors = []
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (card.wrap.supType !== 'multi' && !card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.$c_ac = true
+    card.$c_sc = true
+    
+    card.errors = checkComponent(card)
     
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
-
-    card.action.forEach(cell => {
-      if (cell.hidden === 'true') return
-      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-        if (!cell.modal || cell.modal.fields.length === 0) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-        }
-      } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-        card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-      } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-        card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-      }
-    })
-
-    card.subcards.forEach((item, i) => {
-      let linkbtn = item.setting.linkbtn || ''
-      item.elements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-          if (linkbtn && linkbtn === cell.uuid) {
-            linkbtn = ''
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
-
-      if (item.setting.type === 'multi' && appType !== 'mob') {
-        item.backElements.forEach(cell => {
-          if (cell.eleType === 'button') {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-            if (linkbtn && linkbtn === cell.uuid) {
-              linkbtn = ''
-            }
-          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-          }
-        })
-      }
-
-      if (linkbtn) {
-        card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
-      }
-    })
 
     this.setState({
       card: card
@@ -576,6 +503,10 @@
         this.addSearch(res)
       }
     } else if (type === 'action') {
+      if (res.style) {
+        delete res.style.width
+        delete res.style.float
+      }
       if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) {
         resolve({status: false, message: '绉诲姩绔笉鏀寔姝ょ被鍨嬬殑鎸夐挳銆�'})
       } else {
@@ -639,7 +570,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/card/double-data-card/index.jsx b/src/menu/components/card/double-data-card/index.jsx
index 30a4940..c4b9072 100644
--- a/src/menu/components/card/double-data-card/index.jsx
+++ b/src/menu/components/card/double-data-card/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -167,88 +167,15 @@
       return
     }
 
-    card.errors = []
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!card.setting.subKey) {
-      card.errors.push({ level: 0, detail: '鏈缃瓙琛ㄤ富閿紒'})
-    } else if (!card.setting.subBID) {
-      card.errors.push({ level: 0, detail: '鏈缃瓙琛˙ID锛�'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.$c_ac = true
+    card.$c_sc = true
+    
+    card.errors = checkComponent(card)
     
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
-
-    card.action.forEach(cell => {
-      if (cell.hidden === 'true') return
-      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-        if (!cell.modal || cell.modal.fields.length === 0) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-        }
-      } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-        card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-      } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-        card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-      }
-    })
-
-    card.subcards.forEach((item, i) => {
-      let linkbtn = item.setting.linkbtn || ''
-      item.elements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-          if (linkbtn && linkbtn === cell.uuid) {
-            linkbtn = ''
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
-
-      item.backElements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-          if (linkbtn && linkbtn === cell.uuid) {
-            linkbtn = ''
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
-
-      if (linkbtn) {
-        card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
-      }
-    })
 
     this.setState({
       card: card
@@ -634,7 +561,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index e5931fd..b914926 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from '../data-card/options'
@@ -139,8 +139,6 @@
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
   updateComponent = (card) => {
-    const { appType } = this.state
-
     card.width = card.wrap.width
     card.name = card.wrap.name
 
@@ -153,133 +151,14 @@
       return
     }
 
-    card.errors = []
+    card.$c_ds = card.wrap.datatype === 'dynamic'
+    card.$c_ac = false
+    card.$c_sc = true
+    
+    card.errors = checkComponent(card)
 
-    if (card.subcards.length === 0) {
-      card.errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
-    }
-
-    if (card.wrap.datatype === 'static') {
+    if (card.errors.length === 0) {
       card.$tables = getTables(card)
-
-      card.subcards.forEach((item, i) => {
-        let linkbtn = item.setting.linkbtn || ''
-
-        item.elements.forEach(cell => {
-          if (cell.eleType === 'button') {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-            if (linkbtn && linkbtn === cell.uuid) {
-              linkbtn = ''
-            }
-          } else if (cell.datatype === 'dynamic' && cell.field) {
-            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-          }
-        })
-
-        if (item.setting.type === 'multi' && appType !== 'mob') {
-          item.backElements.forEach(cell => {
-            if (cell.eleType === 'button') {
-              if (cell.hidden === 'true') return
-              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-                if (!cell.modal || cell.modal.fields.length === 0) {
-                  card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-                }
-              } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-              } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-              }
-              if (linkbtn && linkbtn === cell.uuid) {
-                linkbtn = ''
-              }
-            } else if (cell.datatype === 'dynamic' && cell.field) {
-              card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-            }
-          })
-        }
-
-        if (linkbtn) {
-          card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
-        }
-      })
-    } else {
-      let columns = card.columns.map(c => c.field)
-
-      if (card.wrap.datatype === 'dynamic') {
-        if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-          card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-        } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-          card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-        } else if (!card.setting.primaryKey) {
-          card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-        } else if (!columns.includes(card.setting.primaryKey)) {
-          card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-        } else if (!card.setting.supModule) {
-          card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-        }
-      }
-
-      if (card.errors.length === 0) {
-        card.$tables = getTables(card)
-      }
-
-      card.subcards.forEach((item, i) => {
-        let linkbtn = item.setting.linkbtn || ''
-        item.elements.forEach(cell => {
-          if (cell.eleType === 'button') {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-            if (linkbtn && linkbtn === cell.uuid) {
-              linkbtn = ''
-            }
-          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-          }
-        })
-
-        if (item.setting.type === 'multi' && appType !== 'mob') {
-          item.backElements.forEach(cell => {
-            if (cell.eleType === 'button') {
-              if (cell.hidden === 'true') return
-              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-                if (!cell.modal || cell.modal.fields.length === 0) {
-                  card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-                }
-              } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-              } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-              }
-              if (linkbtn && linkbtn === cell.uuid) {
-                linkbtn = ''
-              }
-            } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-              card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-            }
-          })
-        }
-
-        if (linkbtn) {
-          card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
-        }
-      })
     }
 
     this.setState({
@@ -552,7 +431,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index f856cb6..5eb5acd 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from '../data-card/options'
@@ -161,61 +161,15 @@
       return
     }
 
-    card.errors = []
-
-    // let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
-    // if (supModule === 'empty') {
-    //   supModule = ''
-    // }
-    let columns = card.columns.map(c => c.field)
-    // let lowcols = card.columns.map(c => c.field.toLowerCase())
-
-    if (card.subcards.length === 0) {
-      card.errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
-    }
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.$c_ac = false
+    card.$c_sc = true
+    
+    card.errors = checkComponent(card)
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
-
-    card.subcards.forEach((item, i) => {
-      let linkbtn = item.setting.linkbtn || ''
-      item.elements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-          if (linkbtn && linkbtn === cell.uuid) {
-            linkbtn = ''
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
-
-      if (linkbtn) {
-        card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
-      }
-    })
 
     this.setState({
       card: card
@@ -520,7 +474,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/carousel/data-card/index.jsx b/src/menu/components/carousel/data-card/index.jsx
index cc1938a..5d84aea 100644
--- a/src/menu/components/carousel/data-card/index.jsx
+++ b/src/menu/components/carousel/data-card/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -127,44 +127,15 @@
       return
     }
 
-    card.errors = []
-
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.$c_ac = false
+    card.$c_sc = true
+    
+    card.errors = checkComponent(card)
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
-
-    card.subcards.forEach((item, i) => {
-      item.elements.forEach(cell => {
-        if (cell.eleType === 'button') {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-            }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
-        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-        }
-      })
-    })
 
     this.setState({
       card: card
@@ -275,7 +246,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/carousel/prop-card/index.jsx b/src/menu/components/carousel/prop-card/index.jsx
index 67e23af..755b7e7 100644
--- a/src/menu/components/carousel/prop-card/index.jsx
+++ b/src/menu/components/carousel/prop-card/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from '../data-card/options'
@@ -126,69 +126,14 @@
       return
     }
 
-    card.errors = []
+    card.$c_ds = card.wrap.datatype === 'dynamic'
+    card.$c_ac = false
+    card.$c_sc = true
+    
+    card.errors = checkComponent(card)
 
-    if (card.subcards.length === 0) {
-      card.errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
-    }
-
-    if (card.wrap.datatype === 'static') {
+    if (card.errors.length === 0) {
       card.$tables = getTables(card)
-      card.subcards.forEach(item => {
-        item.elements.forEach(cell => {
-          if (cell.eleType === 'button') {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-          } else if (cell.datatype === 'dynamic' && cell.field) {
-            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-          }
-        })
-      })
-    } else {
-      let columns = card.columns.map(c => c.field)
-
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
-
-      if (card.errors.length === 0) {
-        card.$tables = getTables(card)
-      }
-
-      card.subcards.forEach((item, i) => {
-        item.elements.forEach(cell => {
-          if (cell.eleType === 'button') {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-          }
-        })
-      })
     }
 
     this.setState({
@@ -350,7 +295,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/chart/antv-G6/index.jsx b/src/menu/components/chart/antv-G6/index.jsx
index 81c0e09..985a6f5 100644
--- a/src/menu/components/chart/antv-G6/index.jsx
+++ b/src/menu/components/chart/antv-G6/index.jsx
@@ -8,7 +8,7 @@
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
 import './index.scss'
 
 const { Util } = G6
@@ -1348,21 +1348,9 @@
     card.width = card.plot.width
     card.name = card.plot.name
     card.subtype = card.plot.subtype
-    card.errors = []
-
-    let columns = card.columns.map(c => c.field)
     
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.errors = checkComponent(card)
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
@@ -1370,6 +1358,15 @@
     
     if (!card.plot.valueField) {
       card.errors.push({ level: 0, detail: '鍥捐〃淇℃伅灏氭湭璁剧疆锛�'})
+    } else {
+      let columns = card.columns.map(c => c.field)
+      if (!columns.includes(card.plot.valueField)) {
+        card.errors.push({ level: 0, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      } else if (!columns.includes(card.plot.labelField)) {
+        card.errors.push({ level: 0, detail: '鏂囨湰瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
+      } else if (!columns.includes(card.plot.parentField)) {
+        card.errors.push({ level: 0, detail: '涓婄骇瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
+      }
     }
 
     this.setState({
@@ -1421,12 +1418,12 @@
           <ToolOutlined/>
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
-        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
+        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
         <div className="component-name">
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index 8f865eb..4000502 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -9,7 +9,7 @@
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
 import { chartColors } from '@/utils/option.js'
 import './index.scss'
@@ -1220,48 +1220,37 @@
 
     card.width = card.plot.width
     card.name = card.plot.name
-    card.errors = []
 
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.$c_ac = this.state.appType !== 'mob'
+    
+    card.errors = checkComponent(card)
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
-    
+
+    let columns = card.columns.map(c => c.field)
     if (!card.plot.Xaxis) {
       card.errors.push({ level: 0, detail: '鍧愭爣杞村皻鏈缃紒'})
     } else if (card.plot.datatype === 'query') {
       if (!columns.includes(card.plot.Xaxis)) {
-        card.errors.push({ level: 1, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+        card.errors.push({ level: 0, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
       }
       if (card.plot.Yaxis) {
         card.plot.Yaxis.forEach(m => {
           if (!columns.includes(m)) {
-            card.errors.push({ level: 1, detail: `Y杞翠腑瀛楁鈥�${m}鈥濆凡澶辨晥`})
+            card.errors.push({ level: 0, detail: `Y杞翠腑瀛楁鈥�${m}鈥濆凡澶辨晥`})
           }
         })
       }
     } else if (card.plot.datatype === 'statistics') {
       if (!columns.includes(card.plot.Xaxis)) {
-        card.errors.push({ level: 1, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
-      }
-      if (!columns.includes(card.plot.InfoType)) {
-        card.errors.push({ level: 1, detail: '鍥捐〃涓粺璁$被鍨嬪瓧娈靛凡澶辨晥'})
-      }
-      if (!columns.includes(card.plot.InfoValue)) {
-        card.errors.push({ level: 1, detail: '鍥捐〃涓粺璁″�煎瓧娈靛凡澶辨晥'})
+        card.errors.push({ level: 0, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      } else if (!columns.includes(card.plot.InfoType)) {
+        card.errors.push({ level: 0, detail: '鍥捐〃涓粺璁$被鍨嬪瓧娈靛凡澶辨晥'})
+      } else if (!columns.includes(card.plot.InfoValue)) {
+        card.errors.push({ level: 0, detail: '鍥捐〃涓粺璁″�煎瓧娈靛凡澶辨晥'})
       }
     }
 
@@ -1377,7 +1366,7 @@
           <ToolOutlined/>
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
-        <div className="canvas" id={card.uuid + 'canvas'}></div>
+        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'}></div>
         {appType !== 'mob' ? <ActionComponent
           config={card}
           updateaction={this.updateComponent}
@@ -1386,7 +1375,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/chart/antv-dashboard/index.jsx b/src/menu/components/chart/antv-dashboard/index.jsx
index b66d1d3..f74d260 100644
--- a/src/menu/components/chart/antv-dashboard/index.jsx
+++ b/src/menu/components/chart/antv-dashboard/index.jsx
@@ -8,7 +8,7 @@
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
 import './index.scss'
 
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
@@ -473,30 +473,18 @@
     card.width = card.plot.width
     card.name = card.plot.name
 
-    card.errors = []
-
-    let columns = card.columns.map(c => c.field)
+    card.$c_ds = true
+    card.errors = checkComponent(card)
     
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
-
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
     
+    let columns = card.columns.map(c => c.field)
     if (!card.plot.valueField) {
       card.errors.push({ level: 0, detail: '鏄剧ず鍊煎皻鏈缃紒'})
     } else if (!columns.includes(card.plot.valueField)) {
-      card.errors.push({ level: 1, detail: '鏄剧ず鍊煎湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      card.errors.push({ level: 0, detail: '鏄剧ず鍊煎湪瀛楁闆嗕腑涓嶅瓨鍦�'})
     }
     
     this.setState({
@@ -550,12 +538,12 @@
           <ToolOutlined/>
         </Popover>
         <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
-        <div className="canvas" id={card.uuid + 'dashboard'}></div>
+        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'dashboard'}></div>
         <div className="component-name">
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/chart/antv-pie/index.jsx b/src/menu/components/chart/antv-pie/index.jsx
index 3f269b4..304484c 100644
--- a/src/menu/components/chart/antv-pie/index.jsx
+++ b/src/menu/components/chart/antv-pie/index.jsx
@@ -9,7 +9,7 @@
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
 import './index.scss'
 
@@ -622,22 +622,10 @@
 
     card.width = card.plot.width
     card.name = card.plot.name
-    card.errors = []
-
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
-
+    
+    card.$c_ds = true
+    card.errors = checkComponent(card)
+    
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
@@ -645,11 +633,11 @@
     if (!card.plot.Xaxis) {
       card.errors.push({ level: 0, detail: '鍚嶇О瀛楁灏氭湭璁剧疆锛�'})
     } else {
+      let columns = card.columns.map(c => c.field)
       if (!columns.includes(card.plot.Xaxis)) {
-        card.errors.push({ level: 1, detail: '鍚嶇О瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
-      }
-      if (!columns.includes(card.plot.Yaxis)) {
-        card.errors.push({ level: 1, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+        card.errors.push({ level: 0, detail: '鍚嶇О瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
+      } else if (!columns.includes(card.plot.Yaxis)) {
+        card.errors.push({ level: 0, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'})
       }
     }
     
@@ -724,12 +712,12 @@
           <ToolOutlined />
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
-        <div className="canvas" id={card.uuid + 'canvas'}></div>
+        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'}></div>
         <div className="component-name">
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/chart/antv-scatter/index.jsx b/src/menu/components/chart/antv-scatter/index.jsx
index 79b4684..bf2a909 100644
--- a/src/menu/components/chart/antv-scatter/index.jsx
+++ b/src/menu/components/chart/antv-scatter/index.jsx
@@ -8,7 +8,7 @@
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
 import './index.scss'
 
@@ -253,22 +253,12 @@
 
     card.width = card.plot.width
     card.name = card.plot.name
-    card.errors = []
-
-    let columns = card.columns.map(c => c.field)
     
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
-
+    card.$c_ds = true
+    card.$c_ac = this.state.appType !== 'mob'
+    
+    card.errors = checkComponent(card)
+    
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
     }
@@ -276,11 +266,11 @@
     if (!card.plot.Xaxis) {
       card.errors.push({ level: 0, detail: '鍧愭爣杞村皻鏈缃紒'})
     } else {
+      let columns = card.columns.map(c => c.field)
       if (!columns.includes(card.plot.Xaxis)) {
-        card.errors.push({ level: 1, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
-      }
-      if (!columns.includes(card.plot.Yaxis)) {
-        card.errors.push({ level: 1, detail: 'Y杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+        card.errors.push({ level: 0, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      } else if (!columns.includes(card.plot.Yaxis)) {
+        card.errors.push({ level: 0, detail: 'Y杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
       }
     }
 
@@ -395,13 +385,13 @@
           <ToolOutlined/>
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
-        <div className="canvas" id={card.uuid + 'canvas'}></div>
+        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'}></div>
         {appType !== 'mob' ? <ActionComponent config={card} updateaction={this.updateComponent}/> : null}
         <div className="component-name">
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/chart/chart-custom/index.jsx b/src/menu/components/chart/chart-custom/index.jsx
index d601ba4..16d9daf 100644
--- a/src/menu/components/chart/chart-custom/index.jsx
+++ b/src/menu/components/chart/chart-custom/index.jsx
@@ -10,7 +10,7 @@
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
 import './index.scss'
 
@@ -183,21 +183,9 @@
 
     card.width = card.plot.width
     card.name = card.plot.name
-    card.errors = []
 
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+    card.errors = checkComponent(card)
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
diff --git a/src/menu/components/code/sandbox/index.jsx b/src/menu/components/code/sandbox/index.jsx
index cced2c3..1df42b8 100644
--- a/src/menu/components/code/sandbox/index.jsx
+++ b/src/menu/components/code/sandbox/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle } from '@/utils/utils-custom.js'
+import { resetStyle, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import getWrapForm from './options'
 
@@ -102,20 +102,9 @@
 
     card.errors = []
 
-    let columns = card.columns.map(c => c.field)
-
     if (card.wrap.datatype !== 'static') {
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.errors = checkComponent(card)
     }
 
     this.setState({
diff --git a/src/menu/components/editor/braft-editor/index.jsx b/src/menu/components/editor/braft-editor/index.jsx
index 85d22a1..3dfb6b3 100644
--- a/src/menu/components/editor/braft-editor/index.jsx
+++ b/src/menu/components/editor/braft-editor/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { getTables } from '@/utils/utils-custom.js'
+import { getTables, checkComponent } from '@/utils/utils-custom.js'
 import getWrapForm from './options'
 import MKEmitter from '@/utils/events.js'
 
@@ -117,20 +117,9 @@
 
     card.errors = []
 
-    let columns = card.columns.map(c => c.field)
-
     if (card.wrap.datatype !== 'static') {
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
diff --git a/src/menu/components/form/simple-form/index.jsx b/src/menu/components/form/simple-form/index.jsx
index 049c02d..a3ad770 100644
--- a/src/menu/components/form/simple-form/index.jsx
+++ b/src/menu/components/form/simple-form/index.jsx
@@ -9,7 +9,7 @@
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { getModalForm } from '@/templates/zshare/formconfig'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -132,19 +132,9 @@
       if (supModule === 'empty') {
         supModule = ''
       }
-      let columns = card.columns.map(c => c.field)
 
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
@@ -443,6 +433,8 @@
           fieldrepet = true
         }
 
+        delete item.focus
+
         if (item.uuid === res.uuid) {
           if (item.style) {
             res.style = item.style
@@ -581,8 +573,6 @@
     _card.subcards[0].setting.enable = _card.wrap.enable
     _card.subcards[0].setting.verticalSpace = _card.wrap.verticalSpace
 
-    
-
     if (_card.wrap.closeEnable === 'true' && !_card.subcards[0].closeButton) {
       _card.subcards[0].closeButton = {label: '鍏抽棴', enable: 'true', type: 'close', style: {backgroundColor: '#ffffff', color: 'rgba(0,0,0,0.65)', borderColor: '#d9d9d9', borderWidth: '1px', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px', marginLeft: '10px'}}
     } else if (_card.subcards[0].closeButton) {
@@ -673,7 +663,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/form/step-form/index.jsx b/src/menu/components/form/step-form/index.jsx
index 71a2b3a..b256034 100644
--- a/src/menu/components/form/step-form/index.jsx
+++ b/src/menu/components/form/step-form/index.jsx
@@ -9,7 +9,7 @@
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { getModalForm } from '@/templates/zshare/formconfig'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -139,19 +139,9 @@
       if (supModule === 'empty') {
         supModule = ''
       }
-      let columns = card.columns.map(c => c.field)
-
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      
+      card.$c_ds = true
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
@@ -545,6 +535,8 @@
           fieldrepet = true
         }
 
+        delete item.focus
+
         if (item.uuid === res.uuid) {
           if (item.style) {
             res.style = item.style
@@ -795,7 +787,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx
index 0d1e4f1..7f30bd1 100644
--- a/src/menu/components/form/tab-form/index.jsx
+++ b/src/menu/components/form/tab-form/index.jsx
@@ -9,7 +9,7 @@
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { getModalForm } from '@/templates/zshare/formconfig'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from '../step-form/options'
@@ -151,19 +151,9 @@
       if (supModule === 'empty') {
         supModule = ''
       }
-      let columns = card.columns.map(c => c.field)
 
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
@@ -550,6 +540,8 @@
           fieldrepet = true
         }
 
+        delete item.focus
+
         if (item.uuid === res.uuid) {
           if (item.style) {
             res.style = item.style
@@ -797,7 +789,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/group/normal-group/index.jsx b/src/menu/components/group/normal-group/index.jsx
index b635bea..2786f97 100644
--- a/src/menu/components/group/normal-group/index.jsx
+++ b/src/menu/components/group/normal-group/index.jsx
@@ -1,8 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, Button, Modal } from 'antd'
-import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, PrinterOutlined, UngroupOutlined } from '@ant-design/icons'
+import { Popover, Modal } from 'antd'
+import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, UngroupOutlined } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -187,7 +187,7 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        {group.setting && group.setting.print === 'true' ? <Button className="print-button" onClick={this.print}><PrinterOutlined /></Button> : null}
+        {/* {group.setting && group.setting.print === 'true' ? <Button className="print-button" onClick={this.print}><PrinterOutlined /></Button> : null} */}
         <GroupComponents config={group} handleList={this.updateComponent} deleteCard={this.deleteCard} />
       </div>
     )
diff --git a/src/menu/components/group/normal-group/options.jsx b/src/menu/components/group/normal-group/options.jsx
index 0d128ce..8b4c290 100644
--- a/src/menu/components/group/normal-group/options.jsx
+++ b/src/menu/components/group/normal-group/options.jsx
@@ -42,63 +42,61 @@
       precision: 0,
       required: true
     },
-    {
-      type: 'radio',
-      field: 'print',
-      label: '鎵撳嵃鎸夐挳',
-      initval: setting.print || 'false',
-      required: false,
-      options: [
-        {value: 'true', label: '鏄剧ず'},
-        {value: 'false', label: '闅愯棌'},
-      ],
-      controlFields: [
-        {field: 'pageSize', values: ['true']},
-        {field: 'pageLayout', values: ['true']},
-        {field: 'syncModule', values: ['true']},
-        {field: 'checkAll', values: ['true']},
-        {field: 'hide', values: ['true']},
-      ],
-      forbid: appType === 'mob'
-    },
-    {
-      type: 'radio',
-      field: 'pageSize',
-      label: '鎵撳嵃灏哄',
-      initval: setting.pageSize || 'A4',
-      required: true,
-      options: [
-        {value: 'A3', label: 'A3'},
-        {value: 'A4', label: 'A4'},
-        {value: 'A5', label: 'A5'},
-      ],
-      forbid: appType === 'mob'
-    },
-    {
-      type: 'radio',
-      field: 'pageLayout',
-      label: '鎵撳嵃甯冨眬',
-      initval: setting.pageLayout || 'vertical',
-      required: true,
-      options: [
-        {value: 'vertical', label: '绾靛悜'},
-        {value: 'horizontal', label: '妯悜'},
-      ],
-      forbid: appType === 'mob'
-    },
-    {
-      type: 'checkbox',
-      field: 'hide',
-      label: '闅愯棌鍏冪礌',
-      initval: setting.hide || [],
-      tooltip: '鎵ц鎵撳嵃鏃堕渶瑕侀殣钘忕殑椤甸潰鍏冪礌銆�',
-      required: false,
-      options: [
-        {value: 'search', label: '鎼滅储'},
-        {value: 'button', label: '鎸夐挳'},
-      ],
-      forbid: appType === 'mob'
-    },
+    // {
+    //   type: 'radio',
+    //   field: 'print',
+    //   label: '鎵撳嵃鎸夐挳',
+    //   initval: setting.print || 'false',
+    //   required: false,
+    //   options: [
+    //     {value: 'true', label: '鏄剧ず'},
+    //     {value: 'false', label: '闅愯棌'},
+    //   ],
+    //   controlFields: [
+    //     {field: 'pageSize', values: ['true']},
+    //     {field: 'pageLayout', values: ['true']},
+    //     {field: 'hide', values: ['true']},
+    //   ],
+    //   forbid: appType === 'mob'
+    // },
+    // {
+    //   type: 'radio',
+    //   field: 'pageSize',
+    //   label: '鎵撳嵃灏哄',
+    //   initval: setting.pageSize || 'A4',
+    //   required: true,
+    //   options: [
+    //     {value: 'A3', label: 'A3'},
+    //     {value: 'A4', label: 'A4'},
+    //     {value: 'A5', label: 'A5'},
+    //   ],
+    //   forbid: appType === 'mob'
+    // },
+    // {
+    //   type: 'radio',
+    //   field: 'pageLayout',
+    //   label: '鎵撳嵃甯冨眬',
+    //   initval: setting.pageLayout || 'vertical',
+    //   required: true,
+    //   options: [
+    //     {value: 'vertical', label: '绾靛悜'},
+    //     {value: 'horizontal', label: '妯悜'},
+    //   ],
+    //   forbid: appType === 'mob'
+    // },
+    // {
+    //   type: 'checkbox',
+    //   field: 'hide',
+    //   label: '闅愯棌鍏冪礌',
+    //   initval: setting.hide || [],
+    //   tooltip: '鎵ц鎵撳嵃鏃堕渶瑕侀殣钘忕殑椤甸潰鍏冪礌銆�',
+    //   required: false,
+    //   options: [
+    //     {value: 'search', label: '鎼滅储'},
+    //     {value: 'button', label: '鎸夐挳'},
+    //   ],
+    //   forbid: appType === 'mob'
+    // },
     {
       type: 'radio',
       field: 'permission',
diff --git a/src/menu/components/iframe/index.jsx b/src/menu/components/iframe/index.jsx
index d0f2d38..f6ef55f 100644
--- a/src/menu/components/iframe/index.jsx
+++ b/src/menu/components/iframe/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import getWrapForm from './options'
 import './index.scss'
@@ -93,19 +93,8 @@
       card.errors = []
 
       if (card.wrap.datatype === 'dynamic') {
-        let columns = card.columns.map(c => c.field)
-    
-        if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-          card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-        } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-          card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-        } else if (!card.setting.primaryKey) {
-          card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-        } else if (!columns.includes(card.setting.primaryKey)) {
-          card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-        } else if (!card.setting.supModule) {
-          card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-        }
+        card.$c_ds = true
+        card.errors = checkComponent(card)
       }
 
       if (card.errors.length === 0) {
@@ -175,7 +164,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/module/voucher/index.jsx b/src/menu/components/module/voucher/index.jsx
index beb0972..905ef23 100644
--- a/src/menu/components/module/voucher/index.jsx
+++ b/src/menu/components/module/voucher/index.jsx
@@ -158,8 +158,8 @@
                 妯℃澘绫诲瀷:
                 <div>鏃ュ父鏀嚭<DownOutlined/></div>
               </div>
-              <Button className="out-background header-btn">鍏抽棴</Button>
-              <Button className="add-background header-btn">淇濆瓨</Button>
+              <Button className="close-temp header-btn">鍏抽棴</Button>
+              <Button className="save-temp header-btn">淇濆瓨</Button>
             </div> : null}
             <VoucherTable config={card}/>
             {card.wrap.type === 'createVoucher' || card.wrap.type === 'checkVoucher' ? <div className="user">鍒跺崟浜猴細</div> : null}
diff --git a/src/menu/components/module/voucher/index.scss b/src/menu/components/module/voucher/index.scss
index f7b22db..964fd36 100644
--- a/src/menu/components/module/voucher/index.scss
+++ b/src/menu/components/module/voucher/index.scss
@@ -134,6 +134,16 @@
     border-color: rgb(50, 197, 210);
     color: #ffffff;
   }
+  .save-temp {
+    background-color: #1890ff;
+    border-color: #1890ff;
+    color: #ffffff;
+  }
+  .close-temp {
+    background-color: #ffffff;
+    border-color: #f5222d;
+    color: #f5222d;
+  }
 
   .system-background {
     background: #1890ff;
diff --git a/src/menu/components/module/voucher/options.jsx b/src/menu/components/module/voucher/options.jsx
index bd1bee2..2d78725 100644
--- a/src/menu/components/module/voucher/options.jsx
+++ b/src/menu/components/module/voucher/options.jsx
@@ -18,6 +18,17 @@
     }
   })
 
+  let menulist = sessionStorage.getItem('fstMenuList')
+  if (menulist) {
+    try {
+      menulist = JSON.parse(menulist)
+    } catch (e) {
+      menulist = []
+    }
+  } else {
+    menulist = []
+  }
+
   modules = modules.filter(item => !bookids.includes(item.value))
 
   const wrapForm = [
@@ -134,6 +145,16 @@
       tooltip: '琛ㄦ牸涓讳綋閮ㄥ垎涓ょ鐨勭┖鐧借窛绂伙紝琛ㄦ牸鍦ㄧ紪杈戞椂涓ょ浼氭湁娣诲姞鍜屽垹闄ゅ浘鏍囥��',
       required: false
     },
+    {
+      type: 'cascader',
+      field: 'linkmenu',
+      label: '鍒锋柊鑿滃崟',
+      initval: wrap.linkmenu || [],
+      tooltip: '鐐瑰嚮鍏抽棴鏃堕渶瑕佸埛鏂扮殑鑿滃崟銆�',
+      required: false,
+      allowClear: true,
+      options: menulist
+    }
   ]
 
   return wrapForm
diff --git a/src/menu/components/module/voucher/voucherTable/index.scss b/src/menu/components/module/voucher/voucherTable/index.scss
index e8175c8..4b99f1f 100644
--- a/src/menu/components/module/voucher/voucherTable/index.scss
+++ b/src/menu/components/module/voucher/voucherTable/index.scss
@@ -50,6 +50,7 @@
           height: 60px;
           line-height: 60px;
           text-align: center;
+          border-right: 1px solid #d8d8d8;
 
           .ant-table-header-column {
             display: block;
@@ -88,6 +89,7 @@
         padding: 0;
         height: 60px;
         vertical-align: top;
+        border-right: 1px solid #d8d8d8;
 
         .content-wrap {
           padding: 5px;
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index fe83c62..2708d3d 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -416,7 +416,7 @@
         <div className="component-name">
           <div className="center" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 91acca3..8167d07 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -701,6 +701,9 @@
       }, {
         value: 'light',
         text: '鐏�'
+      }, {
+        value: 'system',
+        text: '绯荤粺'
       }]
     },
     {
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 1d43e47..93e5bd9 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -405,28 +405,32 @@
             }
           } else {
             btn.style = item.style || {}
-            if (btn.class !== item.class || btn.show !== item.show || !btn.style.color || item.focus) {
-              if (btn.show === 'icon') {
-                btn.style.color = color[btn.class]
-                btn.style.backgroundColor = 'transparent'
-              } else if (btn.class === 'default') {
-                btn.style.color = 'rgba(0, 0, 0, 0.65)'
-                btn.style.backgroundColor = '#fff'
-                btn.style.borderColor = '#d9d9d9'
-              } else if (btn.class.indexOf('border') > -1) {
-                let _c = btn.class.replace('border-', '')
-                btn.style.color = color[_c]
-                btn.style.backgroundColor = '#fff'
-                btn.style.borderColor = color[_c]
-              } else if (btn.class === 'gray') {
-                btn.style.color = 'rgba(0, 0, 0, 0.65)'
-                btn.style.backgroundColor = color[btn.class]
-                btn.style.borderColor = color[btn.class]
-              } else {
-                btn.style.color = '#ffffff'
-                btn.style.backgroundColor = color[btn.class]
-                btn.style.borderColor = color[btn.class]
+            if (btn.class) {
+              if (btn.class !== item.class || btn.show !== item.show || !btn.style.color || item.focus) {
+                if (btn.show === 'icon') {
+                  btn.style.color = color[btn.class]
+                  btn.style.backgroundColor = 'transparent'
+                } else if (btn.class === 'default') {
+                  btn.style.color = 'rgba(0, 0, 0, 0.65)'
+                  btn.style.backgroundColor = '#fff'
+                  btn.style.borderColor = '#d9d9d9'
+                } else if (btn.class.indexOf('border') > -1) {
+                  let _c = btn.class.replace('border-', '')
+                  btn.style.color = color[_c]
+                  btn.style.backgroundColor = '#fff'
+                  btn.style.borderColor = color[_c]
+                } else if (btn.class === 'gray') {
+                  btn.style.color = 'rgba(0, 0, 0, 0.65)'
+                  btn.style.backgroundColor = color[btn.class]
+                  btn.style.borderColor = color[btn.class]
+                } else {
+                  btn.style.color = '#ffffff'
+                  btn.style.backgroundColor = color[btn.class]
+                  btn.style.borderColor = color[btn.class]
+                }
               }
+            } else if (btn.color) {
+              btn.style = {}
             }
           }
           return btn
diff --git a/src/menu/components/share/actioncomponent/index.scss b/src/menu/components/share/actioncomponent/index.scss
index 63c17eb..193c640 100644
--- a/src/menu/components/share/actioncomponent/index.scss
+++ b/src/menu/components/share/actioncomponent/index.scss
@@ -55,5 +55,8 @@
     .swiper-light {
       background-color: #cccccc;
     }
+    .swiper-system {
+      background-color: #1890ff;
+    }
   }
 }
\ No newline at end of file
diff --git a/src/menu/components/share/markcomponent/index.jsx b/src/menu/components/share/markcomponent/index.jsx
index 53a2a73..c188601 100644
--- a/src/menu/components/share/markcomponent/index.jsx
+++ b/src/menu/components/share/markcomponent/index.jsx
@@ -34,6 +34,15 @@
         editable: true,
         inputType: 'cascader',
         options: [],
+        rules: [{
+          validator: (rule, value, callback) => {
+            if (value[1] === 'dynamic' && value[0] === value[2]) {
+              callback('瀵规瘮瀛楁涓嶅彲鐩稿悓锛�')
+            } else {
+              callback()
+            }
+          }
+        }],
         render: text => {
           return (
             <div>{text[0]}  VS  {text[2] ? text[2] : '闈欐�佸��'}</div>
diff --git a/src/menu/components/share/markcomponent/markform/index.jsx b/src/menu/components/share/markcomponent/markform/index.jsx
index f4adc4d..0603b31 100644
--- a/src/menu/components/share/markcomponent/markform/index.jsx
+++ b/src/menu/components/share/markcomponent/markform/index.jsx
@@ -53,6 +53,15 @@
                   {
                     required: true,
                     message: '璇烽�夋嫨瀵规瘮瀛楁!'
+                  },
+                  {
+                    validator: (rule, value, callback) => {
+                      if (value[1] === 'dynamic' && value[0] === value[2]) {
+                        callback('瀵规瘮瀛楁涓嶅彲鐩稿悓锛�')
+                      } else {
+                        callback()
+                      }
+                    }
                   }
                 ]
               })(
diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx
index aa7abd3..51ae57d 100644
--- a/src/menu/components/share/pastecomponent/index.jsx
+++ b/src/menu/components/share/pastecomponent/index.jsx
@@ -56,6 +56,11 @@
       item.setting.width = item.setting.width || 6
       delete item.$cardType
 
+      if (config.type === 'carousel') {
+        delete item.setting.linkbtn
+        delete item.backElements
+      }
+
       if (item.elements) {
         item.elements = item.elements.map(cell => {
           cell.uuid = Utils.getuuid()
@@ -134,6 +139,10 @@
         this.setState({visible: false})
         return
       } else if (type === 'action') {
+        if (res.style) {
+          delete res.style.width
+          delete res.style.float
+        }
         if (['line', 'bar', 'scatter'].includes(config.type) && !['excelOut', 'excelIn'].includes(res.OpenType)) {
           notification.warning({ top: 92, message: '鍥捐〃涓笉鏀寔姝ょ被鎸夐挳锛�', duration: 5 })
           return
diff --git a/src/menu/components/table/base-table/index.jsx b/src/menu/components/table/base-table/index.jsx
index bd16cd3..70765a7 100644
--- a/src/menu/components/table/base-table/index.jsx
+++ b/src/menu/components/table/base-table/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { getTables } from '@/utils/utils-custom.js'
+import { getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import getWrapForm from './options'
 import Utils from '@/utils/utils.js'
@@ -168,76 +168,14 @@
    */
   updateComponent = (card) => {
     if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
-      card.errors = []
-
-      let doubleClick = card.wrap.doubleClick || ''
-  
-      let columns = card.columns.map(c => c.field)
-  
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.$c_ac = true
+      card.$c_cl = true
+      
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
-      }
-
-      card.action.forEach(cell => {
-        if (cell.hidden === 'true' || cell.origin) return
-        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-          if (!cell.modal || cell.modal.fields.length === 0) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-          }
-        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-        }
-        
-        if (doubleClick === cell.uuid) {
-          doubleClick = ''
-        }
-      })
-  
-      card.cols.forEach(col => {
-        if (col.type === 'action') {
-          col.elements.forEach(cell => {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-
-            if (doubleClick === cell.uuid) {
-              doubleClick = ''
-            }
-          })
-        } else if (col.type === 'custom') {
-          col.elements.forEach(cell => {
-            if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-              card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-            }
-          })
-        } else if (col.field && !columns.includes(col.field)) {
-          card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑瀛楁鈥�${col.field}鈥濇棤鏁坄})
-        }
-      })
-      
-      if (doubleClick) {
-        card.errors.push({ level: 1, detail: `缁戝畾鐨勫弻鍑绘寜閽凡鍒犻櫎`})
       }
     }
 
diff --git a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
index 4808dbf..b0d7621 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -374,6 +374,24 @@
       tooltip: '鍖呮嫭鏂囨湰鎴栨暟鍊煎洖杞︿簨浠躲�佷笅鎷夎彍鍗曢�変腑浜嬩欢銆佸紑鍏冲垏鎹簨浠躲��',
       options: editCols
     },
+    {
+      type: 'select',
+      key: 'ctrlField',
+      label: '绂佺敤瀛楁',
+      initVal: card.ctrlField || '',
+      tooltip: '鎺у埗鍗曞厓鏍兼槸鍚﹀彲浠ョ紪杈戙��',
+      allowClear: true,
+      required: false,
+      options: fields
+    },
+    {
+      type: 'text',
+      key: 'ctrlValue',
+      label: '绂佺敤鍊�',
+      initVal: card.ctrlValue || '',
+      tooltip: '澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�',
+      required: false
+    },
     // {
     //   type: 'radio',
     //   key: 'footEnter',
diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.jsx b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
index 9fe0f6d..ba7f32b 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -60,6 +60,10 @@
     let _options = fromJS(columnTypeOptions[this.column.type]).toJS()
 
     if (this.column.editable === 'true') {
+      _options.push('ctrlField')
+      if (this.column.ctrlField) {
+        _options.push('ctrlValue')
+      }
       if (this.column.type === 'text') {
         _options.push('editType')
 
@@ -170,7 +174,7 @@
       }
     } else if (key === 'format' && value === 'percent') {
       this.props.form.setFieldsValue({postfix: '%'})
-    } else if (key === 'editable' || key === 'editType' || key === 'resourceType') {
+    } else if (key === 'editable' || key === 'editType' || key === 'resourceType' || key === 'ctrlField') {
       let _options = this.getOptions()
 
       this.setState({
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index afa1eba..eb85458 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -695,8 +695,7 @@
         </DndProvider>
         <EditColumn column={card} columns={this.state.columns} fields={fields} submitCol={this.submitCol} cancelCol={this.cancelCol}/>
         <Modal
-          wrapClassName="model-table-action-verify-modal"
-          title={'缂栬緫'}
+          wrapClassName="mk-pop-modal"
           visible={visible}
           width={'75vw'}
           maskClosable={false}
diff --git a/src/menu/components/table/edit-table/index.jsx b/src/menu/components/table/edit-table/index.jsx
index dd661ef..fd53e91 100644
--- a/src/menu/components/table/edit-table/index.jsx
+++ b/src/menu/components/table/edit-table/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import getWrapForm from './options'
 import Utils from '@/utils/utils.js'
@@ -104,10 +104,6 @@
           }
           return col
         })
-        
-        if (_card.wrap.doubleClick) {
-          _card.wrap.doubleClick = oriUids[_card.wrap.doubleClick] || ''
-        }
       }
 
       this.updateComponent(_card)
@@ -157,63 +153,15 @@
     card.name = card.wrap.name
 
     if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
-      card.errors = []
-
-      let columns = card.columns.map(c => c.field)
-
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.$c_ac = true
+      card.$c_cl = true
+      
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
       }
-  
-      card.action.forEach(cell => {
-        if (cell.hidden === 'true') return
-        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-          if (!cell.modal || cell.modal.fields.length === 0) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-          }
-        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-        }
-      })
-  
-      card.cols.forEach(col => {
-        if (col.type === 'action') {
-          col.elements.forEach(cell => {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-          })
-        } else if (col.type === 'custom') {
-          col.elements.forEach(cell => {
-            if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-              card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-            }
-          })
-        } else if (col.field && !columns.includes(col.field)) {
-          card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑瀛楁鈥�${col.field}鈥濇棤鏁坄})
-        }
-      })
     }
 
     this.setState({
@@ -425,7 +373,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/table/edit-table/options.jsx b/src/menu/components/table/edit-table/options.jsx
index 9e47b44..e3c2fb5 100644
--- a/src/menu/components/table/edit-table/options.jsx
+++ b/src/menu/components/table/edit-table/options.jsx
@@ -295,6 +295,18 @@
       ]
     },
     {
+      type: 'radio',
+      field: 'empty',
+      label: '绌哄�奸殣钘�',
+      initval: wrap.empty || 'show',
+      tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
+      required: false,
+      options: [
+        {value: 'show', label: '鍚�'},
+        {value: 'hidden', label: '鏄�'},
+      ],
+    },
+    {
       type: 'multiselect',
       field: 'blacklist',
       label: '榛戝悕鍗�',
diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index 917976c..755b5c9 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -346,7 +346,10 @@
 
   pasteCell = (col, cell, resolve) => {
     resolve({status: true})
-    
+    if (cell.copyType === 'action') {
+      cell.eleType = 'button'
+    }
+
     delete cell.copyType
     cell.uuid = Utils.getuuid()
     cell.focus = true
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index 898bda5..e1e95f3 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import getWrapForm from './options'
 import Utils from '@/utils/utils.js'
@@ -195,74 +195,14 @@
     card.name = card.wrap.name
 
     if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
-      card.errors = []
-
-      let doubleClick = card.wrap.doubleClick || ''
-  
-      let columns = card.columns.map(c => c.field)
-  
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.$c_ac = true
+      card.$c_cl = true
+      
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
-      }
-
-      card.action.forEach(cell => {
-        if (cell.hidden === 'true') return
-        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-          if (!cell.modal || cell.modal.fields.length === 0) {
-            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-          }
-        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-        }
-        if (doubleClick === cell.uuid) {
-          doubleClick = ''
-        }
-      })
-  
-      card.cols.forEach(col => {
-        if (col.type === 'action') {
-          col.elements.forEach(cell => {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-            if (doubleClick === cell.uuid) {
-              doubleClick = ''
-            }
-          })
-        } else if (col.type === 'custom') {
-          col.elements.forEach(cell => {
-            if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-              card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-            }
-          })
-        } else if (col.field && !columns.includes(col.field)) {
-          card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑瀛楁鈥�${col.field}鈥濇棤鏁坄})
-        }
-      })
-      
-      if (doubleClick) {
-        card.errors.push({ level: 1, detail: `缁戝畾鐨勫弻鍑绘寜閽凡鍒犻櫎`})
       }
     }
 
@@ -484,7 +424,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/timeline/normal-timeline/index.jsx b/src/menu/components/timeline/normal-timeline/index.jsx
index 826bfae..cb58209 100644
--- a/src/menu/components/timeline/normal-timeline/index.jsx
+++ b/src/menu/components/timeline/normal-timeline/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -109,44 +109,14 @@
     card.width = card.wrap.width
     card.name = card.wrap.name
     if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
-      card.errors = []
-
-      let columns = card.columns.map(c => c.field)
-  
-      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-      } else if (!card.setting.primaryKey) {
-        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-      } else if (!columns.includes(card.setting.primaryKey)) {
-        card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-      } else if (!card.setting.supModule) {
-        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-      }
+      card.$c_ds = true
+      card.$c_sc = true
+      
+      card.errors = checkComponent(card)
 
       if (card.errors.length === 0) {
         card.$tables = getTables(card)
       }
-
-      card.subcards.forEach(col => {
-        col.elements.forEach(cell => {
-          if (cell.eleType === 'button') {
-            if (cell.hidden === 'true') return
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (!cell.modal || cell.modal.fields.length === 0) {
-                card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-              }
-            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-            }
-          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
-          }
-        })
-      })
     }
     
     this.setState({
@@ -224,7 +194,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/components/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx
index 8e91c46..c7afa92 100644
--- a/src/menu/components/tree/antd-tree/index.jsx
+++ b/src/menu/components/tree/antd-tree/index.jsx
@@ -6,7 +6,7 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -101,21 +101,9 @@
     card.width = card.wrap.width
     card.name = card.wrap.name
 
-    card.errors = []
-
-    let columns = card.columns.map(c => c.field)
-
-    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
-      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
-    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
-      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
-    } else if (!card.setting.primaryKey) {
-      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
-    } else if (!columns.includes(card.setting.primaryKey)) {
-      card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
-    } else if (!card.setting.supModule) {
-      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
-    }
+    card.$c_ds = true
+      
+    card.errors = checkComponent(card)
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
@@ -123,6 +111,15 @@
 
     if (!card.wrap.parentField || !card.wrap.valueField || !card.wrap.labelField) {
       card.errors.push({ level: 0, detail: '鏈缃熀鏈俊鎭紒'})
+    } else {
+      let columns = card.columns.map(c => c.field)
+      if (!columns.includes(card.wrap.parentField)) {
+        card.errors.push({ level: 0, detail: '涓婄骇瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
+      } else if (!columns.includes(card.wrap.valueField)) {
+        card.errors.push({ level: 0, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      } else if (!columns.includes(card.wrap.labelField)) {
+        card.errors.push({ level: 0, detail: '鏂囨湰瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
+      }
     }
 
     this.setState({
@@ -259,7 +256,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx
index 2de2760f..27d9a81 100644
--- a/src/menu/datasource/index.jsx
+++ b/src/menu/datasource/index.jsx
@@ -206,6 +206,12 @@
         res.subColumns.reverse()
       }
 
+      if (this.verifyRef.state.debugId) {
+        res.setting.debugId = this.verifyRef.state.debugId
+      } else {
+        delete res.setting.debugId
+      }
+
       this.setState({loading: false, visible: false})
       this.props.updateConfig({...config, ...res})
     }, () => {
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index a8e1e0f..e557a15 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -212,7 +212,8 @@
       median: _setting,
       searches: search,
       defaultSearch: _search,
-      searchKey: ''
+      searchKey: '',
+      debugId: _setting.debugId || ''
     })
 
     this.getsysScript()
@@ -679,7 +680,7 @@
 
     if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) {
       let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-      let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch, timestamp)
+      let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch, '2023-04-20 15:29:37')
 
       let _debugId = md5(r.sql)
 
@@ -722,8 +723,9 @@
           if (sumParam) {
             Api.genericInterface(sumParam).then(res => {
               if (res.status) {
-                this.setState({debugId: _debugId})
-                resolve()
+                this.setState({debugId: _debugId}, () => {
+                  resolve()
+                })
               } else {
                 reject()
                 Modal.error({
@@ -732,8 +734,9 @@
               }
             })
           } else {
-            this.setState({debugId: _debugId})
-            resolve()
+            this.setState({debugId: _debugId}, () => {
+              resolve()
+            })
           }
         } else {
           reject()
diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx
index 3295cea..235cd21 100644
--- a/src/menu/datasource/verifycard/settingform/index.jsx
+++ b/src/menu/datasource/verifycard/settingform/index.jsx
@@ -535,6 +535,23 @@
                 )}
               </Form.Item>
             </Col> : null}
+            {config.type === 'interface' && setting.supModule && setting.supModule[0] === 'empty' ? <Col span={8}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鍒濆鍖栧姞杞藉皢鍦ㄩ〉闈㈠姞杞藉墠鎵ц銆�">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  鍔犺浇鏂瑰紡
+                </Tooltip>
+              }>
+                {getFieldDecorator('loadlevel', {
+                  initialValue: setting.loadlevel || 'default'
+                })(
+                  <Radio.Group onChange={(e) => {this.onOptionChange(e.target.value, 'loadlevel')}}>
+                    <Radio value="default">榛樿</Radio>
+                    <Radio value="init">鍒濆鍖�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
             {config.type === 'interface' ? <Col span={8}>
               <Form.Item label="瀹氭椂鍣�">
                 {getFieldDecorator('timer', {
diff --git a/src/menu/modalconfig/controller.jsx b/src/menu/modalconfig/controller.jsx
index 683598d..5a7c777 100644
--- a/src/menu/modalconfig/controller.jsx
+++ b/src/menu/modalconfig/controller.jsx
@@ -35,6 +35,8 @@
       config: fromJS(config).toJS(),
       btn: fromJS(btn).toJS()
     })
+
+    window.GLOB.formId = ''
   }
 
   handleBack = () => {
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
index 0448d06..0a90bda 100644
--- a/src/menu/modalconfig/index.jsx
+++ b/src/menu/modalconfig/index.jsx
@@ -238,6 +238,8 @@
           fieldrepet = true
         }
 
+        delete item.focus
+
         if (item.uuid === res.uuid) {
           if (item.style) {
             res.style = item.style
@@ -516,7 +518,7 @@
 
   render () {
     const { btn } = this.props
-    const { config, saving } = this.state
+    const { config, saving, card } = this.state
 
     return (
       <div className="modal-form-board">
@@ -581,7 +583,7 @@
           </div>
         </DndProvider>
         <Modal
-          title="缂栬緫"
+          title={card && card.$copy ? '澶嶅埗' : '缂栬緫'}
           visible={this.state.visible}
           width={950}
           maskClosable={false}
@@ -591,7 +593,7 @@
           destroyOnClose
         >
           <ModalForm
-            card={this.state.card}
+            card={card}
             formlist={this.state.formlist}
             inputSubmit={this.handleSubmit}
             standardform={this.state.standardform}
diff --git a/src/menu/sysinterface/index.jsx b/src/menu/sysinterface/index.jsx
index 240fea2..e957516 100644
--- a/src/menu/sysinterface/index.jsx
+++ b/src/menu/sysinterface/index.jsx
@@ -52,7 +52,6 @@
         dataIndex: 'operation',
         render: (text, record) =>
           (<div style={{textAlign: 'center'}}>
-            <DataSource config={record} updateConfig={this.update}/>
             <span onClick={() => this.handleStatus(record)} style={{color: '#8E44AD', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><SwapOutlined /></span>
             <span onClick={() => this.copy(record)} style={{color: '#26C281', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><CopyOutlined /></span>
             <Popconfirm
@@ -60,8 +59,9 @@
               title="纭畾鍒犻櫎锛�"
               onConfirm={() => this.deleteScript(record)
             }>
-              <span style={{color: '#ff4d4f', cursor: 'pointer', fontSize: '16px'}}><DeleteOutlined /></span>
+              <span style={{color: '#ff4d4f', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><DeleteOutlined /></span>
             </Popconfirm>
+            <DataSource config={record} updateConfig={this.update}/>
           </div>)
       }
     ]
@@ -253,7 +253,7 @@
 
     return (
       <div className="mk-sys-interface" style={{display: 'inline-block'}}>
-        <Button className="mk-border-green" onClick={this.trigger}><DatabaseOutlined /> 鍏叡鏁版嵁婧�</Button>
+        <Button className="mk-border-danger" onClick={this.trigger}><DatabaseOutlined /> 鍏叡鏁版嵁婧�</Button>
         <Modal
           title="鍏叡鏁版嵁婧�"
           wrapClassName="interface-controller-modal"
diff --git a/src/mob/components/formdragelement/index.jsx b/src/mob/components/formdragelement/index.jsx
index bfeaf84..838e79d 100644
--- a/src/mob/components/formdragelement/index.jsx
+++ b/src/mob/components/formdragelement/index.jsx
@@ -62,6 +62,8 @@
     let val = JSON.parse(JSON.stringify(_card))
     val.copyType = 'form'
 
+    _card.$copy = true
+
     delete val.$srcId
     
     let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
diff --git a/src/mob/components/search/single-search/index.jsx b/src/mob/components/search/single-search/index.jsx
index 323851c..05f64e5 100644
--- a/src/mob/components/search/single-search/index.jsx
+++ b/src/mob/components/search/single-search/index.jsx
@@ -144,7 +144,7 @@
         <div className="component-name">
           <div className="center" onDoubleClick={() => {
             let oInput = document.createElement('input')
-            oInput.value = card.uuid
+            oInput.value = 'anchor' + card.uuid
             document.body.appendChild(oInput)
             oInput.select()
             document.execCommand('Copy')
diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx
index b355b14..97841a6 100644
--- a/src/mob/modalconfig/index.jsx
+++ b/src/mob/modalconfig/index.jsx
@@ -235,6 +235,8 @@
           fieldrepet = true
         }
 
+        delete item.focus
+
         if (item.uuid === res.uuid) {
           if (item.style) {
             res.style = item.style
@@ -469,7 +471,7 @@
 
   render () {
     const { btn } = this.props
-    const { config, saving } = this.state
+    const { config, saving, card } = this.state
 
     return (
       <div className="mob-form-board">
@@ -518,7 +520,7 @@
           </div>
         </DndProvider>
         <Modal
-          title="缂栬緫"
+          title={card && card.$copy ? '澶嶅埗' : '缂栬緫'}
           visible={this.state.visible}
           width={950}
           maskClosable={false}
@@ -528,7 +530,7 @@
           destroyOnClose
         >
           <ModalForm
-            card={this.state.card}
+            card={card}
             formlist={this.state.formlist}
             inputSubmit={this.handleSubmit}
             standardform={this.state.standardform}
diff --git a/src/pc/components/login/normal-login/index.jsx b/src/pc/components/login/normal-login/index.jsx
index 60a3e17..e5e741d 100644
--- a/src/pc/components/login/normal-login/index.jsx
+++ b/src/pc/components/login/normal-login/index.jsx
@@ -197,7 +197,7 @@
           <div className="center">
             <div className="title" onDoubleClick={() => {
               let oInput = document.createElement('input')
-              oInput.value = card.uuid
+              oInput.value = 'anchor' + card.uuid
               document.body.appendChild(oInput)
               oInput.select()
               document.execCommand('Copy')
diff --git a/src/router/index.js b/src/router/index.js
index b384ad4..5a7b168 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,7 +1,5 @@
 import React, {Component} from 'react'
 import {HashRouter, Switch, Route, Redirect} from 'react-router-dom'
-import md5 from 'md5'
-import moment from 'moment'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncLoadComponent from '@/utils/asyncLoadComponent'
 
@@ -28,59 +26,36 @@
 const SystemProc = asyncLoadComponent(() => import('@/views/systemproc'))
 
 const routers = [
-  {path: '/login', name: 'login', component: Login, auth: false},
-  {path: '/main', name: 'main', component: Main, auth: true},
-  {path: '/pay/:param', name: 'pay', component: Pay, auth: false},
-  {path: '/print/:param', name: 'print', component: PrintT, auth: false},
-  {path: '/ssologin/:param', name: 'ssologin', component: Sso, auth: false},
-  {path: '/design', name: 'design', component: Design, auth: true},
-  {path: '/appmanage', name: 'appmanage', component: AppManage, auth: true},
-  {path: '/appcheck', name: 'appcheck', component: AppCheck, auth: true},
-  {path: '/pcdesign/:param', name: 'pcdesign', component: PCDesign, auth: true},
-  {path: '/mobdesign/:param', name: 'mobdesign', component: MobDesign, auth: true},
-  {path: '/imdesign/:param', name: 'imdesign', component: ImDesign, auth: true},
-  {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true},
-  {path: '/basedesign/:param', name: 'basedesign', component: BaseDesign, auth: true},
-  {path: '/tabledesign/:param', name: 'tabledesign', component: TableDesign, auth: true},
-  {path: '/billprint/:param', name: 'billprint', component: BillPrint, auth: true},
-  {path: '/docprint/:menuId', name: 'docprint', component: BillPrint, auth: false},
-  {path: '/docprint/:menuId/:id', name: 'docprint', component: BillPrint, auth: false},
-  {path: '/tab/:menuId', name: 'tab', component: MainParams, auth: false},
-  {path: '/role/:param', name: 'role', component: RoleManage, auth: true},
-  {path: '/hs', name: 'hs', component: SystemFunc, auth: true},
-  {path: '/proc', name: 'proc', component: SystemProc, auth: true},
-  {path: '/interface', name: 'interface', component: Interface, auth: true}
+  {path: '/login', name: 'login', component: Login},
+  {path: '/main', name: 'main', component: Main},
+  {path: '/pay/:param', name: 'pay', component: Pay},
+  {path: '/print/:param', name: 'print', component: PrintT},
+  {path: '/ssologin/:param', name: 'ssologin', component: Sso},
+  {path: '/design', name: 'design', component: Design},
+  {path: '/appmanage', name: 'appmanage', component: AppManage},
+  {path: '/appcheck', name: 'appcheck', component: AppCheck},
+  {path: '/pcdesign/:param', name: 'pcdesign', component: PCDesign},
+  {path: '/mobdesign/:param', name: 'mobdesign', component: MobDesign},
+  {path: '/imdesign/:param', name: 'imdesign', component: ImDesign},
+  {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign},
+  {path: '/basedesign/:param', name: 'basedesign', component: BaseDesign},
+  {path: '/tabledesign/:param', name: 'tabledesign', component: TableDesign},
+  {path: '/billprint/:param', name: 'billprint', component: BillPrint},
+  {path: '/docprint/:menuId', name: 'docprint', component: BillPrint},
+  {path: '/docprint/:menuId/:id', name: 'docprint', component: BillPrint},
+  {path: '/tab/:menuId', name: 'tab', component: MainParams},
+  {path: '/role/:param', name: 'role', component: RoleManage},
+  {path: '/hs', name: 'hs', component: SystemFunc},
+  {path: '/proc', name: 'proc', component: SystemProc},
+  {path: '/interface', name: 'interface', component: Interface}
 ]
 
 export default class RouteConfig extends Component {
-  controlRoute (item, props) {
-    if (!item.auth) { // 涓嶉渶瑕佹巿鏉冿紝鐩存帴璺宠浆
-      return (<item.component {...props}/>)
-    }
-    
-    let userId = sessionStorage.getItem('UserID') // 鍒ゆ柇鐧诲綍淇℃伅鏄惁瀛樺湪锛屾敞鐢ㄦ埛鍙兘淇濆瓨涓婚〉閾炬帴
-    let authCode = localStorage.getItem(window.location.href.split('#')[0] + 'AuthCode') // 鍒ゆ柇绯荤粺鏄惁鍦ㄦ巿鏉冩湡闄愬唴
-    let _s = md5('mksoft' + moment().format('YYYYMMDD'))
-    let isauth = authCode && authCode.includes(_s)
-    let key = md5(window.GLOB.appId + 'minke_software' + window.GLOB.appkey).toUpperCase().substr(-6)
-    let key1 = window.GLOB.licenseKey ? window.GLOB.licenseKey.substring(0, 6) : ''
-
-    if (key1 === key) {
-      isauth = true
-    }
-
-    if (userId && isauth) {
-      return (<item.component {...props}/>)
-    } else {
-      return (<Redirect to={{ pathname: '/login'}}/>)
-    }
-  }
-
   render () {
     return (
       <HashRouter>
         <Switch>
-          {routers.map((item, index) => <Route key={index} path={item.path} name={item.name} exact render={ props => this.controlRoute(item, props)}/>)}
+          {routers.map((item, index) => <Route key={index} path={item.path} name={item.name} exact render={ props => <item.component {...props}/>}/>)}
           <Redirect exact from="/" to="login"/>
           <Route component= {NotFound}/>
         </Switch>
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index 98f672e..fe8bcec 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -496,6 +496,7 @@
   checkAll = () => {
     const { config, data, selectedData } = this.state
 
+    if (config.wrap.cardType !== 'checkbox') return
     if (!data || data.length === 0) return
     
     if (selectedData.length === 0 || selectedData.length < data.length) {
diff --git a/src/tabviews/custom/components/card/double-data-card/index.jsx b/src/tabviews/custom/components/card/double-data-card/index.jsx
index b3fc0da..e010304 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.jsx
+++ b/src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -392,6 +392,7 @@
   checkAll = () => {
     const { config, data, selectedData } = this.state
 
+    if (config.wrap.cardType !== 'checkbox') return
     if (!data || data.length === 0) return
     
     if (selectedData.length === 0 || selectedData.length < data.length) {
diff --git a/src/tabviews/custom/components/group/normal-group/index.jsx b/src/tabviews/custom/components/group/normal-group/index.jsx
index 631caf0..ff504f4 100644
--- a/src/tabviews/custom/components/group/normal-group/index.jsx
+++ b/src/tabviews/custom/components/group/normal-group/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Col, notification, Button, Row } from 'antd'
+import { Col, notification, Row } from 'antd'
 
 import Api from '@/api'
 import asyncComponent from '@/utils/asyncComponent'
@@ -44,7 +44,7 @@
 
   state = {
     mainSearch: [],
-    printing: false,
+    // printing: false,
     data: null
   }
 
@@ -296,101 +296,101 @@
     })
   }
 
-  canvasToImage(canvas) {
-    let image = new Image()
-    image.src = canvas.toDataURL('image/jpg')
-    image.style = 'width:100%;height:100%;position:absolute;z-index:1;left:0px;top:0px;'
-    return image
-  }
+  // canvasToImage(canvas) {
+  //   let image = new Image()
+  //   image.src = canvas.toDataURL('image/jpg')
+  //   image.style = 'width:100%;height:100%;position:absolute;z-index:1;left:0px;top:0px;'
+  //   return image
+  // }
 
-  print = () => {
-    const { config } = this.props
-    const { printing } = this.state
+  // print = () => {
+  //   const { config } = this.props
+  //   const { printing } = this.state
 
-    if (printing) return
-    this.setState({printing: true})
+  //   if (printing) return
+  //   this.setState({printing: true})
 
-    let qrcodes = document.getElementsByClassName('qrcode-box')
+  //   let qrcodes = document.getElementsByClassName('qrcode-box')
 
-    for (let i = 0; i < qrcodes.length; i++) {
-      let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
+  //   for (let i = 0; i < qrcodes.length; i++) {
+  //     let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
 
-      if (canvas) {
-        let img = this.canvasToImage(canvas)
+  //     if (canvas) {
+  //       let img = this.canvasToImage(canvas)
   
-        canvas.remove()
-        qrcodes[i].append(img)
-      }
-    }
+  //       canvas.remove()
+  //       qrcodes[i].append(img)
+  //     }
+  //   }
 
-    let pageSize = ['A4', 'A3', 'A5'].includes(config.setting.pageSize) ? config.setting.pageSize : 'A4'
-    let pageLayout = config.setting.pageLayout !== 'horizontal' ? 'vertical' : 'horizontal'
-    let hides = config.setting.hide || []
+  //   let pageSize = ['A4', 'A3', 'A5'].includes(config.setting.pageSize) ? config.setting.pageSize : 'A4'
+  //   let pageLayout = config.setting.pageLayout !== 'horizontal' ? 'vertical' : 'horizontal'
+  //   let hides = config.setting.hide || []
 
-    let pageParam = {
-      A4: {
-        vertical: 980,
-        horizontal: 1200,
-      },
-      A3: {
-        vertical: 1200,
-        horizontal: 1600,
-      },
-      A5: {
-        vertical: 700,
-        horizontal: 1000,
-      }
-    }
+  //   let pageParam = {
+  //     A4: {
+  //       vertical: 980,
+  //       horizontal: 1200,
+  //     },
+  //     A3: {
+  //       vertical: 1200,
+  //       horizontal: 1600,
+  //     },
+  //     A5: {
+  //       vertical: 700,
+  //       horizontal: 1000,
+  //     }
+  //   }
 
-    let width = pageParam[pageSize][pageLayout]
+  //   let width = pageParam[pageSize][pageLayout]
 
-    try {
-      let jubuData =  document.getElementById(config.uuid).innerHTML
+  //   try {
+  //     let jubuData =  document.getElementById(config.uuid).innerHTML
 
-      let iframe = document.createElement('IFRAME')
-      let linkList = document.getElementsByTagName('link')     // 鑾峰彇鐖剁獥鍙ink鏍囩瀵硅薄鍒楄〃
-      let styleList = document.getElementsByTagName('style')   // 鑾峰彇鐖剁獥鍙tyle鏍囩瀵硅薄鍒楄〃
+  //     let iframe = document.createElement('IFRAME')
+  //     let linkList = document.getElementsByTagName('link')     // 鑾峰彇鐖剁獥鍙ink鏍囩瀵硅薄鍒楄〃
+  //     let styleList = document.getElementsByTagName('style')   // 鑾峰彇鐖剁獥鍙tyle鏍囩瀵硅薄鍒楄〃
 
-      document.body.appendChild(iframe)
-      let doc = iframe.contentWindow.document
+  //     document.body.appendChild(iframe)
+  //     let doc = iframe.contentWindow.document
       
-      doc.open()
-      doc.write(`<!DOCTYPE html><html lang="en"><head>`)
-      for (let i = 0;i < linkList.length;i++) {
-        if (linkList[i].type === 'text/css') {
-          doc.write(`<LINK rel="stylesheet" type="text/css" href="${linkList[i].href}">`)
-        }
-      }
-      doc.write(`<style>body{width: ${width}px!important;} *{border-style: solid;border-width: 0;} .print-button{display: none!important;} ${hides.includes('search') ? '.top-search{display: none!important;}' : ''} ${hides.includes('button') ? '.ant-btn{opacity: 0!important;}' : ''}</style>`)
-      for (let i = 0;i < styleList.length;i++) {
-        doc.write('<style>' + styleList[i].innerHTML + '</style>')
-      }
-      doc.write(`</head><body>`)
-      doc.write(jubuData)
-      doc.write(`</body></html>`)
-      doc.close()
+  //     doc.open()
+  //     doc.write(`<!DOCTYPE html><html lang="en"><head>`)
+  //     for (let i = 0;i < linkList.length;i++) {
+  //       if (linkList[i].type === 'text/css') {
+  //         doc.write(`<LINK rel="stylesheet" type="text/css" href="${linkList[i].href}">`)
+  //       }
+  //     }
+  //     doc.write(`<style>body{width: ${width}px!important;} *{border-style: solid;border-width: 0;} .print-button{display: none!important;} ${hides.includes('search') ? '.top-search{display: none!important;}' : ''} ${hides.includes('button') ? '.ant-btn{opacity: 0!important;}' : ''}</style>`)
+  //     for (let i = 0;i < styleList.length;i++) {
+  //       doc.write('<style>' + styleList[i].innerHTML + '</style>')
+  //     }
+  //     doc.write(`</head><body>`)
+  //     doc.write(jubuData)
+  //     doc.write(`</body></html>`)
+  //     doc.close()
 
-      setTimeout(() => {
-        iframe.contentWindow.focus()
-        iframe.contentWindow.print()
+  //     setTimeout(() => {
+  //       iframe.contentWindow.focus()
+  //       iframe.contentWindow.print()
 
-        document.body.removeChild(iframe)
+  //       document.body.removeChild(iframe)
 
-        this.setState({printing: false})
-      }, 500)
-    } catch (e) {
-      this.setState({printing: false})
-      notification.warning({
-        top: 92,
-        message: '鎵撳嵃寮傚父锛�',
-        duration: 5
-      })
-    }
-  }
+  //       this.setState({printing: false})
+  //     }, 500)
+  //   } catch (e) {
+  //     this.setState({printing: false})
+  //     notification.warning({
+  //       top: 92,
+  //       message: '鎵撳嵃寮傚父锛�',
+  //       duration: 5
+  //     })
+  //   }
+  // }
 
   render() {
     const { config } = this.props
-    const { printing } = this.state
+    // const { printing } = this.state
 
     if (!config.components || config.components.length === 0) return (<div style={config.style}></div>)
     
@@ -399,7 +399,7 @@
         {config.setting && config.setting.title ? <div className="group-header" style={config.headerStyle}>
           <span className="title">{config.setting.title}</span>
         </div> : null}
-        {config.setting && config.setting.print === 'true' ? <Button className="print-button" icon="printer" loading={printing} onClick={this.print}></Button> : null}
+        {/* {config.setting && config.setting.print === 'true' ? <Button className="print-button" icon="printer" loading={printing} onClick={this.print}></Button> : null} */}
         <Row className="component-wrap">{this.getComponents()}</Row>
       </div>
     )
diff --git a/src/tabviews/custom/components/interfaces/interItem/index.jsx b/src/tabviews/custom/components/interfaces/interItem/index.jsx
index ab62d9b..3ba9519 100644
--- a/src/tabviews/custom/components/interfaces/interItem/index.jsx
+++ b/src/tabviews/custom/components/interfaces/interItem/index.jsx
@@ -39,9 +39,13 @@
       }
     }
 
-    setTimeout(() => {
-      this.loadData()
-    }, config.setting.delay)
+    if (config.setting.onload !== 'false') {
+      setTimeout(() => {
+        this.loadData()
+      }, config.setting.delay)
+    } else {
+      MKEmitter.addListener('initFinish', this.initFinish)
+    }
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -57,8 +61,21 @@
       return
     }
     this.timer && this.timer.stop()
+    MKEmitter.removeListener('initFinish', this.initFinish)
     MKEmitter.removeListener('reloadData', this.reloadData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
+  }
+
+  initFinish = (MenuID) => {
+    const { config } = this.props
+
+    if (config.MenuID !== MenuID) return
+
+    if (config.setting.onload === 'false') {
+      setTimeout(() => {
+        this.loadData()
+      }, config.setting.delay)
+    }
   }
 
   resetParentParam = (MenuID, id) => {
@@ -111,6 +128,10 @@
 
       MKEmitter.emit('mkPublicData', config.uuid, _data)
       MKEmitter.emit('resetSelectLine', config.uuid, _data.$$uuid, _data)
+
+      if (config.setting.loadlevel === 'init') {
+        MKEmitter.emit('interFinish', config.MenuID, config.uuid)
+      }
     } else {
       this.loading = false
       this.timer && this.timer.stop()
@@ -126,6 +147,10 @@
           duration: 10
         })
       }
+
+      if (config.setting.loadlevel === 'init') {
+        MKEmitter.emit('interFinish', config.MenuID, config.uuid)
+      }
     }
   }
 
diff --git a/src/tabviews/custom/components/module/account/index.jsx b/src/tabviews/custom/components/module/account/index.jsx
index 4996d2c..a4f2cb1 100644
--- a/src/tabviews/custom/components/module/account/index.jsx
+++ b/src/tabviews/custom/components/module/account/index.jsx
@@ -25,6 +25,7 @@
 
   componentDidMount () {
     this.loadData()
+    MKEmitter.addListener('reloadData', this.reloadData)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -37,6 +38,20 @@
   componentWillUnmount () {
     this.setState = () => {
       return
+    }
+    MKEmitter.removeListener('reloadData', this.reloadData)
+  }
+
+  reloadData = (menuId) => {
+    const { config } = this.props
+    const { activeItem } = this.state
+    
+    if (config.uuid !== menuId) return
+
+    if (activeItem) {
+      MKEmitter.emit('resetSelectLine', config.uuid, activeItem.id, activeItem)
+    } else {
+      this.loadData()
     }
   }
 
@@ -171,7 +186,7 @@
 
     return (
       <div className="menu-account-wrap" style={config.style}>
-        {config.wrap.MenuID ? <Select value={activeItem ? activeItem.id : ''} placeholder="璇烽�夋嫨璐﹀" onChange={this.changeBook} dropdownRender={menu => (
+        {config.wrap.MenuID ? <Select showSearch filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} value={activeItem ? activeItem.id : ''} placeholder="璇烽�夋嫨璐﹀" onChange={this.changeBook} dropdownRender={menu => (
           <div>
             {menu}
             <Divider style={{ margin: '4px 0' }} />
@@ -181,11 +196,11 @@
           </div>
         )}>
           {books.map(item => (
-            <Option disabled={!item.months} key={item.id}>{item.account_name}</Option>
+            <Option disabled={!item.months} title={item.account_name} key={item.id}>{item.account_name}</Option>
           ))}
-        </Select> : <Select value={activeItem ? activeItem.id : ''} disabled={config.wrap.readonly === 'true'} placeholder="璇烽�夋嫨璐﹀" onChange={this.changeBook}>
+        </Select> : <Select showSearch filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} value={activeItem ? activeItem.id : ''} disabled={config.wrap.readonly === 'true'} placeholder="璇烽�夋嫨璐﹀" onChange={this.changeBook}>
           {books.map(item => (
-            <Option disabled={!item.months} key={item.id}>{item.account_name}</Option>
+            <Option disabled={!item.months} title={item.account_name} key={item.id}>{item.account_name}</Option>
           ))}
         </Select>}
         {activeItem ? <span className="date">{activeItem.date}</span> : null}
diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx
index c230975..bd07284 100644
--- a/src/tabviews/custom/components/module/voucher/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/index.jsx
@@ -57,7 +57,7 @@
 
     let BID = ''
     let BData = ''
-
+    
     if (config.wrap.supModule) {
       BData = window.GLOB.CacheData.get(config.wrap.supModule)
     } else {
@@ -208,6 +208,8 @@
       let employee = []
       let cash_flow = []
       let others = []
+      let logistics = []
+      let lessor = []
 
       res.sup && res.sup.forEach(item => {
         names[item.sup_type_code] = item.sup_type_name
@@ -215,6 +217,14 @@
 
       res.supplier && res.supplier.forEach(item => {
         supplier.push({value: item.suppliercode, label: item.suppliername})
+      })
+
+      res.logistics && res.logistics.forEach(item => {
+        logistics.push({value: item.suppliercode, label: item.suppliername})
+      })
+
+      res.lessor && res.lessor.forEach(item => {
+        lessor.push({value: item.suppliercode, label: item.suppliername})
       })
 
       res.customer && res.customer.forEach(item => {
@@ -249,6 +259,8 @@
         subjects: res.subjects || [],
         names: names,
         supplier: supplier,
+        logistics: logistics,
+        lessor: lessor,
         customer: customer,
         department: department,
         project: project,
@@ -406,6 +418,14 @@
       } else if (line.sup_accounting && line.supAccounts) {
         line.supAccounts.forEach(item => {
           if (item.sup_acc_type === 'supplier') {
+            if (!item.suppliercode || !item.suppliername) {
+              err = `绗�${_index}琛岋紝璇烽�夋嫨杈呭姪鏍哥畻銆俙
+            }
+          } else if (item.sup_acc_type === 'logistics') {
+            if (!item.suppliercode || !item.suppliername) {
+              err = `绗�${_index}琛岋紝璇烽�夋嫨杈呭姪鏍哥畻銆俙
+            }
+          } else if (item.sup_acc_type === 'lessor') {
             if (!item.suppliercode || !item.suppliername) {
               err = `绗�${_index}琛岋紝璇烽�夋嫨杈呭姪鏍哥畻銆俙
             }
@@ -700,6 +720,14 @@
       } else if (line.sup_accounting && line.supAccounts) {
         line.supAccounts.forEach(item => {
           if (item.sup_acc_type === 'supplier') {
+            if (!item.suppliercode || !item.suppliername) {
+              err = `绗�${_index}琛岋紝璇烽�夋嫨杈呭姪鏍哥畻銆俙
+            }
+          } else if (item.sup_acc_type === 'logistics') {
+            if (!item.suppliercode || !item.suppliername) {
+              err = `绗�${_index}琛岋紝璇烽�夋嫨杈呭姪鏍哥畻銆俙
+            }
+          } else if (item.sup_acc_type === 'lessor') {
             if (!item.suppliercode || !item.suppliername) {
               err = `绗�${_index}琛岋紝璇烽�夋嫨杈呭姪鏍哥畻銆俙
             }
@@ -1020,16 +1048,27 @@
   triggerclose = () => {
     const { config, status } = this.state
 
+    let tabId = ''
+    if (config.wrap.linkmenu && config.wrap.linkmenu.length > 0) {
+      tabId = config.wrap.linkmenu[config.wrap.linkmenu.length - 1]
+    }
+
     if (status === 'change') {
       confirm({
         content: '鍐呭宸插彉鏇达紝纭畾瑕佸叧闂悧锛�',
         onOk() {
           MKEmitter.emit('closeTabView', config.$pageId)
+          if (tabId) {
+            MKEmitter.emit('reloadMenuView', tabId, 'table')
+          }
         },
         onCancel() {}
       })
     } else {
       MKEmitter.emit('closeTabView', config.$pageId)
+      if (tabId) {
+        MKEmitter.emit('reloadMenuView', tabId, 'table')
+      }
     }
   }
 
@@ -1150,8 +1189,8 @@
               </Select>
             </div>
             <div className="temp-action">
-              <Button className="add-background header-btn" onClick={() => this.triggerTempsave()}>淇濆瓨</Button>
-              <Button className="out-background header-btn" onClick={this.triggerclose}>鍏抽棴</Button>
+              <Button className="save-temp header-btn" onClick={() => this.triggerTempsave()}>淇濆瓨</Button>
+              <Button className="close-temp header-btn" onClick={this.triggerclose}>鍏抽棴</Button>
             </div>
           </div> : null}
           <VoucherTable config={config} loading={loading} data={data} onChange={this.dataChange}/>
diff --git a/src/tabviews/custom/components/module/voucher/index.scss b/src/tabviews/custom/components/module/voucher/index.scss
index a2bae1b..4eec234 100644
--- a/src/tabviews/custom/components/module/voucher/index.scss
+++ b/src/tabviews/custom/components/module/voucher/index.scss
@@ -111,6 +111,17 @@
     color: #ffffff;
   }
 
+  .save-temp {
+    background-color: var(--mk-sys-color);
+    border-color: var(--mk-sys-color);
+    color: #ffffff;
+  }
+  .close-temp {
+    background-color: #ffffff;
+    border-color: #f5222d;
+    color: #f5222d;
+  }
+
   .system-background {
     background: var(--mk-sys-color);
     border-color: var(--mk-sys-color);
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
index 2acf108..5e3b17c 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -108,7 +108,7 @@
       let account = {}
 
       subAccounts.forEach(item => {
-        if (item.field === 'supplier') {
+        if (item.field === 'supplier' || item.field === 'logistics' || item.field === 'lessor') {
           account[item.field] = {suppliercode: item.value, suppliername: item.name}
         } else if (item.field === 'customer') {
           account[item.field] = {customercode: item.value, customername: item.name}
@@ -762,7 +762,7 @@
 
             if (record.sup_accounting && record.supAccounts) {
               record.supAccounts.forEach(item => {
-                if (item.sup_acc_type === 'supplier') {
+                if (item.sup_acc_type === 'supplier' || item.sup_acc_type === 'logistics' || item.sup_acc_type === 'lessor') {
                   val += item.suppliercode ? '_' + item.suppliercode + ' ' + item.suppliername : ''
                 } else if (item.sup_acc_type === 'customer') {
                   val += item.customercode ? '_' + item.customercode + ' ' + item.customername : ''
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.scss b/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
index fa2baa2..daf9cb2 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
@@ -50,6 +50,7 @@
           height: 60px;
           line-height: 60px;
           text-align: center;
+          border-right: 1px solid #d8d8d8;
 
           .ant-table-header-column {
             display: block;
@@ -88,6 +89,7 @@
         padding: 0;
         height: 60px;
         vertical-align: top;
+        border-right: 1px solid #d8d8d8;
 
         .content-wrap {
           padding: 0px 5px;
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index 07adac0..993c4db 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -504,6 +504,8 @@
           width: item.Width || 120
         })
       })
+
+      orderfields = null
     }
 
     if (rowspans.length === 0) {
@@ -816,7 +818,9 @@
       pickup: false
     })
 
-    sorter.field = orderfields[sorter.field] || ''
+    if (orderfields) {
+      sorter.field = orderfields[sorter.field] || ''
+    }
 
     this.props.refreshdata(pagination, filters, sorter)
   }
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index 3496def..a0568c2 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -589,10 +589,15 @@
   }
 
   render() {
-    const { BID, setting, actions, config, columns, BData, selectedData, lock } = this.state
+    const { BID, setting, actions, config, columns, BData, data, selectedData, lock } = this.state
+
+    let style = {...config.style}
+    if (config.wrap.empty === 'hidden' && data.length === 0) {
+      style.display = 'none'
+    }
 
     return (
-      <div className="custom-edit-table" id={'anchor' + config.uuid} style={config.style}>
+      <div className="custom-edit-table" id={'anchor' + config.uuid} style={style}>
         <NormalHeader config={config}/>
         {config.search && config.search.length ?
           <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
index 3aea5ea..2efbd4e 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -126,6 +126,9 @@
     const { col, record } = this.props
 
     if (id !== col.uuid + record.$$uuid) return
+
+    if (col.ctrlField && col.ctrlValue.includes(record[col.ctrlField])) return
+
     this.focus()
   }
 
@@ -288,6 +291,11 @@
 
     if (!col) return (<td {...resProps} className={className} style={style}/>)
 
+    let disabled = false
+    if (col.ctrlField) {
+      disabled = col.ctrlValue.includes(record[col.ctrlField])
+    }
+
     let children = null
     if (col.type === 'text') {
       let content = ''
@@ -325,7 +333,7 @@
         }
       }
 
-      if (col.editable === 'true') {
+      if (col.editable === 'true' && !disabled) {
         if (editing) {
           if (!col.editType || col.editType === 'text') {
             return (<td className="editing_table_cell">
@@ -421,7 +429,7 @@
         }
       }
 
-      if (col.editable === 'true') {
+      if (col.editable === 'true' && !disabled) {
         if (editing) {
           return (<td className="editing_table_cell">
             <InputNumber id={col.uuid + record.$$uuid} defaultValue={value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
@@ -685,9 +693,14 @@
     let { col, config, record, style, className } = this.props
     const { err } = this.state
 
+    let disabled = false
+    if (col.ctrlField) {
+      disabled = col.ctrlValue.includes(record[col.ctrlField])
+    }
+
     let children = null
     if (col.type === 'text') {
-      if (col.editable === 'true') {
+      if (col.editable === 'true' && !disabled) {
         let _value = ''
         if (col.editField) {
           _value = record[col.editField] !== undefined ? record[col.editField] : ''
@@ -757,7 +770,7 @@
         children = content
       }
     } else if (col.type === 'number') {
-      if (col.editable === 'true') {
+      if (col.editable === 'true' && !disabled) {
         let _value = record[col.field] !== undefined ? record[col.field] : ''
         children = (<>
           <InputNumber id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress}/>
@@ -947,6 +960,10 @@
             if (!initEditLine) {
               initEditLine = item
             }
+
+            if (item.ctrlField) {
+              item.ctrlValue = item.ctrlValue.split(',')
+            }
           }
     
           if (item.type === 'text' && item.editable === 'true' && item.editType === 'select' && item.resourceType === '1') {
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
index 6d3798c..2d34aea 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -426,6 +426,7 @@
   .main-pickup {
     position: relative;
     z-index: 2;
+    margin-left: 10px;
   }
   .submit-table {
     position: relative;
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 1074471..ff11815 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -70,8 +70,11 @@
     data: null,           // 鍒楄〃鏁版嵁闆�
     loading: false,       // 鍒楄〃鏁版嵁鍔犺浇涓�
     visible: false,       // 鏍囩椤垫帶鍒�
-    shortcuts: null       // 蹇嵎閿�
+    shortcuts: null,      // 蹇嵎閿�
+    loadinginter: false
   }
+
+  stepInter = null
 
   /**
    * @description 鑾峰彇椤甸潰閰嶇疆淇℃伅
@@ -93,6 +96,7 @@
         config = window.decodeURIComponent(window.atob(result.LongParam))
         config = config.replace(/@mywebsite@\//ig, window.GLOB.baseurl)
         config = JSON.parse(config)
+        config.MenuID = MenuID
       } catch (e) {
         console.warn('Parse Failure')
         config = ''
@@ -200,7 +204,9 @@
 
       config.$cache = config.cacheLocal === 'true'
 
-      config.interfaces = this.formatInterSetting(config.interfaces, regs)
+      let initInters = []
+
+      config.interfaces = this.formatInterSetting(config.interfaces, regs, MenuID, initInters)
       config.components = this.filterComponent(config.components, roleId, window.GLOB.mkActions, balMap, skip, param, MenuID, config.interfaces, popview, config.$cache)
       
       // 鑾峰彇涓绘悳绱㈡潯浠�
@@ -236,8 +242,17 @@
         config.components = this.filterBalcony(config.components, balMap)
       }
 
+      if (initInters.length > 0) {
+        this.stepInter = {
+          MenuID: MenuID,
+          inters: initInters,
+          params: params
+        }
+      }
+
       this.setState({
         BID: BID,
+        loadinginter: this.stepInter !== null,
         shortcuts: shortcuts.length > 0 ? shortcuts : null,
         config,
         mainSearch
@@ -251,7 +266,10 @@
           ele.innerHTML = config.normalcss
           document.getElementsByTagName('head')[0].appendChild(ele)
         }
-        if (params.length === 0) {
+
+        if (this.stepInter) {
+
+        } else if (params.length === 0) {
           setTimeout(() => { // 寤舵椂鍔犺浇鐘舵��
             this.setState({
               loadingview: false
@@ -697,6 +715,8 @@
 
           return group
         })
+      } else if (item.subtype === 'voucher') {
+        item.wrap.supModule = item.wrap.supModule.pop()
       }
       
       return true
@@ -941,13 +961,24 @@
   }
 
   // 鏍煎紡鍖栭粯璁よ缃�
-  formatInterSetting = (inters, regs) => {
+  formatInterSetting = (inters, regs, MenuID, initInters) => {
     if (!inters) return []
 
-    let interfaces = inters.filter(m => m.status === 'true')
+    let initlimit = false
+    let interfaces = inters.filter(m => {
+      if (m.status !== 'true') return false
+
+      if (m.setting.loadlevel === 'init') {
+        initlimit = true
+        initInters.push(m.uuid)
+      }
+
+      return true
+    })
 
     let delay = 15
     return interfaces.map(inter => {
+      inter.MenuID = MenuID
       inter.setting.delay = delay
       delay += 15
 
@@ -958,6 +989,10 @@
         } else {
           inter.setting.supModule = ''
         }
+      }
+
+      if (initlimit && inter.setting.loadlevel !== 'init') {
+        inter.setting.onload = 'false'
       }
 
       if (inter.setting.interType !== 'system') return inter
@@ -1074,6 +1109,7 @@
   }
 
   componentDidMount () {
+    MKEmitter.addListener('interFinish', this.interFinish)
     MKEmitter.addListener('debugChange', this.debugChange)
     MKEmitter.addListener('reloadMenuView', this.reloadMenuView)
     MKEmitter.addListener('resetActiveMenu', this.resetActiveMenu)
@@ -1086,6 +1122,7 @@
     this.setState = () => {
       return
     }
+    MKEmitter.removeListener('interFinish', this.interFinish)
     MKEmitter.removeListener('debugChange', this.debugChange)
     MKEmitter.removeListener('reloadMenuView', this.reloadMenuView)
     MKEmitter.removeListener('resetActiveMenu', this.resetActiveMenu)
@@ -1096,6 +1133,30 @@
       this.state.config.interfaces.forEach(m => {
         window.GLOB.CacheData.delete(m.uuid)
       })
+    }
+  }
+
+  interFinish = (MenuID, interId) => {
+    if (!this.stepInter || this.stepInter.MenuID !== MenuID) return
+
+    this.stepInter.inters = this.stepInter.inters.filter(item => item !== interId)
+
+    if (this.stepInter.inters.length === 0) {
+      this.setState({loadinginter: false})
+
+      if (this.stepInter.params.length === 0) {
+        setTimeout(() => { // 寤舵椂鍔犺浇鐘舵��
+          this.setState({
+            loadingview: false
+          })
+        }, 1000)
+      } else {
+        this.loadmaindata(this.stepInter.params)
+      }
+
+      MKEmitter.emit('initFinish', this.stepInter.MenuID)
+
+      this.stepInter = null
     }
   }
 
@@ -1127,6 +1188,8 @@
       })
     }
 
+    this.stepInter = null
+
     this.setState({
       BID: '',              // 椤甸潰璺宠浆鏃舵惡甯D
       loadingview: true,    // 椤甸潰鍔犺浇涓�
@@ -1147,9 +1210,9 @@
   }
 
   getComponents = () => {
-    const { config, BID, data, mainSearch } = this.state
+    const { config, BID, data, mainSearch, loadinginter } = this.state
 
-    if (!config || !config.components) return
+    if (!config || !config.components || loadinginter) return
 
     return config.components.map(item => {
       let style = null
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index 9623d2d..d7f8069 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -426,6 +426,7 @@
       })
     } else if (btn.intertype === 'outer') { // 澶栭儴鎺ュ彛
       let _outParam = null
+      let ver_token = false
 
       new Promise(resolve => {
         // 鍐呴儴璇锋眰
@@ -483,6 +484,7 @@
             } else {
               param.$token = btn.exInterface || ''
             }
+            ver_token = true
           } else {
             if (window.GLOB.systemType === 'production' && btn.proInterface) {
               param.rduri = btn.proInterface
@@ -511,7 +513,9 @@
       }).then(response => {
         if (!response) return
         // 鍥炶皟璇锋眰
-        if (btn.callbackFunc) {
+        if (ver_token && response.ErrMesg === 'token_error') {
+          this.execError(response)
+        } else if (btn.callbackFunc ) {
           // 瀛樺湪鍥炶皟鍑芥暟鏃讹紝璋冪敤
           delete response.message
           delete response.status
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 34d4cbb..2d08e57 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -1008,9 +1008,9 @@
     if (btn.Ot === 'requiredOnce' && selectedData && selectedData.length > 0) {
       primaryId = selectedData.map(d => d.$$uuid || '').filter(Boolean).join(',')
       if (_search && primaryId) {
-        _search += ` and ${primaryKey} in (select ${primaryKey} from dbo.SplitComma('${primaryId}'))`
+        _search += ` and ${primaryKey} in (select ID from dbo.SplitComma('${primaryId}'))`
       } else if (primaryId) {
-        _search = `where ${primaryKey} in (select ${primaryKey} from dbo.SplitComma('${primaryId}'))`
+        _search = `where ${primaryKey} in (select ID from dbo.SplitComma('${primaryId}'))`
       }
     }
 
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 53cdd31..52da922 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -1742,6 +1742,7 @@
   outerOuterRequest = (params, result, record, _resolve) => {
     const { btn } = this.props
     let outParam = JSON.parse(JSON.stringify(result))
+    let ver_token = false
 
     if (btn.outerFunc) {
       result.func = btn.outerFunc
@@ -1780,6 +1781,7 @@
         } else {
           result.$token = btn.exInterface || ''
         }
+        ver_token = true
       } else {
         if (window.GLOB.systemType === 'production' && btn.proInterface) {
           result.rduri = btn.proInterface
@@ -1796,6 +1798,10 @@
 
     Api.genericInterface(result).then(res => {
       if (!res) return // LoginError鏃朵腑鏂姹�
+      if (ver_token && res.ErrMesg === 'token_error') {
+        this.execError(res)
+        return
+      }
       this.outerCallbackRequest(params, res, record, outParam, _resolve)
     }, () => {
       this.outerCallbackRequest(params, {status: false, message: 500, ErrCode: 'E', ErrMesg: 500}, record, outParam, _resolve)
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index 0dceae9..41bcd2f 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1183,6 +1183,7 @@
   printOuterLoopRequest = (params, btn, _list, _resolve) => {
     let param = params.shift()
     let _outParam = null
+    let ver_token = false
 
     new Promise(resolve => {
       // 鍐呴儴璇锋眰
@@ -1240,6 +1241,7 @@
           } else {
             res.$token = btn.exInterface || ''
           }
+          ver_token = true
         } else {
           if (window.GLOB.systemType === 'production' && btn.proInterface) {
             res.rduri = btn.proInterface
@@ -1262,7 +1264,10 @@
     }).then(response => {
       if (!response) return
 
-      if (btn.callbackFunc) {
+      if (ver_token && response.ErrMesg === 'token_error') {
+        this.execError(response)
+        _resolve({next: false, list: []})
+      } else if (btn.callbackFunc) {
         // 瀛樺湪鍥炶皟鍑芥暟鏃讹紝璋冪敤
         delete response.message
         delete response.status
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 35287d8..4a96938 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -410,10 +410,13 @@
 
         let cell = fieldMap.get(item.field)
 
-        if (cell.hidden) return
-
+        // if (cell.hidden) return
+        
         if (supItem.hidden || !item.values.includes(supItem.initval)) {
           cell.hidden = true
+          if (cell.empty === 'hidden') {
+            cell.$hidden = true
+          }
           fieldMap.set(item.field, cell)
         }
 
@@ -834,7 +837,7 @@
           }
         }
 
-        if (item.empty === 'hidden' && item.oriOptions.length > 0) {
+        if (item.empty === 'hidden' && item.oriOptions.length > 0 && !item.$hidden) {
           item.hidden = false
         }
         if (item.type === 'checkcard' && item.readonly && item.unchecked === 'hidden') {
@@ -911,6 +914,10 @@
         let m = map.get(cell.field)
         m.hidden = current.hidden || !cell.values.includes(val)
 
+        if (m.empty === 'hidden' && m.oriOptions.length === 0) {
+          m.hidden = true
+        }
+
         if (m.hidden) {
           m.initval = this.record[m.field]
         }
diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx
index 3cd1b5a..4798f28 100644
--- a/src/templates/modalconfig/dragelement/index.jsx
+++ b/src/templates/modalconfig/dragelement/index.jsx
@@ -62,6 +62,8 @@
     let val = JSON.parse(JSON.stringify(_card))
     val.copyType = 'form'
 
+    _card.$copy = true
+
     delete val.$srcId
     
     let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index 3473421..46f1560 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -1016,7 +1016,7 @@
     }
 
     let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    let sql = SettingUtils.getDebugSql(verify, scripts, (verify.useSearch === 'true' ? searches : []), Utils, timestamp)
+    let sql = SettingUtils.getDebugSql(verify, scripts, (verify.useSearch === 'true' ? searches : []), Utils, '2023-04-20 15:29:37')
 
     let _debugId = md5(sql)
 
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
index 83c35bc..6dbc194 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -616,7 +616,7 @@
     const { verify, declareSql, debugId } = this.state
 
     let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    let sql = SettingUtils.getDebugSql(verify.setting || {}, verify.columns, scripts, declareSql, timestamp)
+    let sql = SettingUtils.getDebugSql(verify.setting || {}, verify.columns, scripts, declareSql, '2023-04-20 15:29:37')
 
     let _debugId = md5(sql)
 
diff --git a/src/templates/zshare/codemirror/index.jsx b/src/templates/zshare/codemirror/index.jsx
index 60376cc..729bb1a 100644
--- a/src/templates/zshare/codemirror/index.jsx
+++ b/src/templates/zshare/codemirror/index.jsx
@@ -167,6 +167,9 @@
         return
       }
 
+      let _href = window.location.href.split('#')[0]
+      localStorage.setItem(_href + 'sql_char', JSON.stringify([res.origin, res.value]))
+
       _sql = _sql.replace(reg, res.value)
 
       this.setState({display: false, defaultVal: _sql}, () => {
diff --git a/src/templates/zshare/codemirror/replaceform/index.jsx b/src/templates/zshare/codemirror/replaceform/index.jsx
index 41a9906..2cf2646 100644
--- a/src/templates/zshare/codemirror/replaceform/index.jsx
+++ b/src/templates/zshare/codemirror/replaceform/index.jsx
@@ -8,6 +8,25 @@
     inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢
   }
 
+  state = {
+    orivalue: '',
+    value: ''
+  }
+
+  UNSAFE_componentWillMount() {
+    let _href = window.location.href.split('#')[0]
+    let res = localStorage.getItem(_href + 'sql_char')
+
+    if (res) {
+      res = JSON.parse(res)
+
+      this.setState({
+        orivalue: res[0] || '',
+        value: res[1] || ''
+      })
+    }
+  }
+
   componentDidMount () {
     try {
       let _form = document.getElementById('origin')
@@ -40,6 +59,7 @@
 
   render() {
     const { getFieldDecorator } = this.props.form
+    const { orivalue, value } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -56,7 +76,7 @@
           <Col span={24}>
             <Form.Item label="鍘熷瓧绗�">
               {getFieldDecorator('origin', {
-                initialValue: '',
+                initialValue: orivalue,
                 rules: [
                   {
                     required: true,
@@ -69,7 +89,7 @@
           <Col span={24}>
             <Form.Item label="鏇挎崲涓�">
               {getFieldDecorator('value', {
-                initialValue: ''
+                initialValue: value
               })(<Input autoComplete="off" onPressEnter={this.enterPress}/>)}
             </Form.Item>
           </Col>
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index c79c9f0..60ea825 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -3935,6 +3935,18 @@
     // },
     {
       type: 'radio',
+      key: 'pickerMode',
+      label: '寮圭獥鏍峰紡',
+      initVal: card.pickerMode || 'default',
+      required: false,
+      options: [
+        {value: 'default', text: '榛樿'},
+        {value: 'board', text: '闈㈡澘'},
+      ],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'radio',
       key: 'empty',
       label: '绌哄�奸殣钘�',
       initVal: card.empty || 'show',
diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx
index 7f13956..75a9a67 100644
--- a/src/templates/zshare/modalform/datatable/index.jsx
+++ b/src/templates/zshare/modalform/datatable/index.jsx
@@ -431,6 +431,8 @@
   }
 
   render() {
+    const { display, fields } = this.props
+
     const components = {
       body: {
         row: DragableBodyRow,
@@ -456,9 +458,9 @@
     })
 
     let addable = false
-    if (this.props.display === 'picture' || this.props.display === 'color') {
+    if (display === 'picture' || display === 'color') {
       addable = true
-    } else if (this.props.fields && this.props.fields.length > 0) {
+    } else if (fields && fields.length > 0) {
       addable = true
     }
 
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index cae1bd2..043f984 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -21,12 +21,12 @@
 const modalTypeOptions = {
   text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl', 'inputType'],
   number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'],
-  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
+  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
   checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
   radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'setAll', 'emptyText', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
   checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'place', 'width', 'multiple', 'splitline', 'marginTop', 'marginBottom'],
   multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom', 'dropdown'],
-  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
+  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
   fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'miniSet', 'splitline', 'marginTop', 'marginBottom', 'maxSize'],
   switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'],
   date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'place', 'marginTop', 'marginBottom', 'minDate', 'maxDate', 'precision'],
@@ -338,6 +338,10 @@
       shows.push('supvalue')
     }
 
+    if (this.record.hidden === 'true') {
+      shows = shows.filter(s => !['supField', 'supvalue', 'tooltip', 'extra', 'enter', 'tabField'].includes(s))
+    }
+
     return {
       shows,
       reOptions,
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 823cb11..94e9705 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -1250,4 +1250,182 @@
   tables = Array.from(new Set(tables))
 
   return tables
+}
+
+/**
+ * @description 妫�娴嬬粍浠跺唴瀹�
+ */
+export function checkComponent (card) {
+  let errors = []
+  let columns = []
+
+  if (card.$c_ds) {
+    columns = card.columns.map(c => c.field)
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!columns.includes(card.setting.primaryKey)) {
+      errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'})
+    } else if (card.subtype === 'dualdatacard') {                     // 鍙岄噸鍗�
+      if (!card.setting.subKey) {
+        errors.push({ level: 0, detail: '鏈缃瓙琛ㄤ富閿紒'})
+      } else if (!card.setting.subBID) {
+        errors.push({ level: 0, detail: '鏈缃瓙琛˙ID锛�'})
+      } else if (!card.setting.supModule) {
+        errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+    } else if (card.type === 'card' && card.subtype === 'datacard') { // 鏁版嵁鍗★紝鍙兘鏈夊涓婄骇
+      if (card.wrap.supType !== 'multi' && !card.setting.supModule) {
+        errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+    } else if (card.type !== 'balcony' && !card.setting.supModule) {  // 鎮诞妗嗕笂绾х粍浠堕渶鍗曠嫭璁剧疆
+      errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+  } else if ((card.type === 'balcony' || card.type === 'card') && card.wrap.datatype === 'public') {
+    columns = card.columns.map(c => c.field)
+  }
+
+  let doubleClick = ''
+  if (card.type === 'table') {
+    doubleClick = card.wrap.doubleClick || ''
+  }
+
+  if (card.$c_ac) {
+    card.action.forEach(cell => {
+      if (cell.hidden === 'true' || cell.origin) return
+      // if (cell.OpenType === 'popview') {
+      //   if (!cell.config) {
+      //     errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑寮圭獥鏍囩灏氭湭璁剧疆`})
+      //   } else if (!cell.config.enabled) {
+      //     errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑寮圭獥鏍囩鏈惎鐢╜})
+      //   }
+      // }
+      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+        if (!cell.modal || cell.modal.fields.length === 0) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+        }
+      } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+      } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+      }
+      if (doubleClick === cell.uuid) {
+        doubleClick = ''
+      }
+    })
+  }
+
+  if (card.$c_sc) {
+    card.subcards.forEach((item, i) => {
+      let linkbtn = item.setting.linkbtn || ''
+      item.elements.forEach(cell => {
+        if (cell.eleType === 'button') {
+          if (cell.hidden === 'true') return
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            }
+          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+          }
+          if (linkbtn && linkbtn === cell.uuid) {
+            linkbtn = ''
+          }
+        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+          errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+        }
+      })
+  
+      if (card.subtype === 'dualdatacard' || (item.setting.type === 'multi' && item.backElements && sessionStorage.getItem('appType') !== 'mob')) {
+        item.backElements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.hidden === 'true') return
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              }
+            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+              errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+              errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+            }
+            if (linkbtn && linkbtn === cell.uuid) {
+              linkbtn = ''
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+            errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+      }
+  
+      if (linkbtn) {
+        errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
+      }
+    })
+
+    if (card.subcards.length === 0) {
+      errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
+    }
+  }
+
+  if (card.$c_el) {
+    card.elements.forEach(cell => {
+      if (cell.eleType === 'button') {
+        if (cell.hidden === 'true') return
+        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+          if (!cell.modal || cell.modal.fields.length === 0) {
+            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+          }
+        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+        }
+      } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+        errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+      }
+    })
+  }
+
+  if (card.$c_cl) {
+    card.cols.forEach(col => {
+      if (col.type === 'action') {
+        col.elements.forEach(cell => {
+          if (cell.hidden === 'true') return
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            }
+          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+          }
+
+          if (doubleClick === cell.uuid) {
+            doubleClick = ''
+          }
+        })
+      } else if (col.type === 'custom') {
+        col.elements.forEach(cell => {
+          if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+            card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+      } else if (col.field && !columns.includes(col.field)) {
+        card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑瀛楁鈥�${col.field}鈥濇棤鏁坄})
+      }
+    })
+
+    if (doubleClick) {
+      card.errors.push({ level: 1, detail: `缁戝畾鐨勫弻鍑绘寜閽凡鍒犻櫎`})
+    }
+  }
+
+  return errors
 }
\ No newline at end of file
diff --git a/src/views/billprint/index.jsx b/src/views/billprint/index.jsx
index 70a2505..1757a88 100644
--- a/src/views/billprint/index.jsx
+++ b/src/views/billprint/index.jsx
@@ -336,6 +336,11 @@
               return cols.map(item => {
                 if (item.type === 'colspan') {
                   item.subcols = getColumns(item.subcols)
+                } else if (item.type === 'custom') {
+                  item.elements = item.elements.map(cell => {
+                    cell = this.resetElement(cell)
+                    return cell
+                  })
                 } else {
                   item.IsSort = 'false'
                 }
@@ -345,6 +350,41 @@
             }
             component.cols = getColumns(component.cols)
             component.statFields = []
+          } else if (['card', 'carousel', 'timeline'].includes(component.type)) {
+            component.subcards && component.subcards.forEach(card => {
+              if (card.style.boxShadow) {
+                delete card.style.hShadow
+                delete card.style.vShadow
+                delete card.style.shadowBlur
+                delete card.style.shadowColor
+              }
+    
+              card.elements = card.elements.filter(cell => {
+                if (cell.eleType === 'button') return false
+   
+                cell = this.resetElement(cell)
+    
+                return true
+              })
+    
+              if (!card.backElements || card.backElements.length === 0) return
+    
+              card.backElements = card.backElements.filter(cell => {
+                if (cell.eleType === 'button') return false
+   
+                cell = this.resetElement(cell)
+    
+                return true
+              })
+            })
+          } else if (component.type === 'balcony') {
+            component.elements = component.elements.filter(cell => {
+              if (cell.eleType === 'button') return false
+                
+              cell = this.resetElement(cell)
+    
+              return true
+            })
           }
 
           if (component.wrap && component.wrap.datatype === 'static') {
@@ -454,6 +494,23 @@
     })
   }
 
+  resetElement = (cell) => {
+    cell.style = cell.style || {}
+    if (['text', 'number', 'formula'].includes(cell.eleType)) {
+      cell.innerHeight = cell.innerHeight || 'auto'
+      cell.alignItems = cell.height > 1 ? cell.alignItems : ''
+
+      if (cell.eleType === 'number' && typeof(cell.decimal) === 'number') {
+        cell.round = Math.pow(10, cell.decimal)
+        if (cell.format === 'percent') {
+          cell.decimal = cell.decimal > 2 ? cell.decimal - 2 : 0
+        }
+      }
+    }
+
+    return cell
+  }
+
   reload = () => {
     const { tempId } = this.state
     
diff --git a/src/views/design/header/editfirstmenu/index.jsx b/src/views/design/header/editfirstmenu/index.jsx
index 58bee24..45a5b8d 100644
--- a/src/views/design/header/editfirstmenu/index.jsx
+++ b/src/views/design/header/editfirstmenu/index.jsx
@@ -141,6 +141,7 @@
         onOk() {
           return Api.getSystemConfig(param).then(res => {
             if (res.status) {
+              that.setState({ change: false })
               that.props.reload()
             } else {
               notification.warning({
diff --git a/src/views/design/sidemenu/editsecmenu/index.jsx b/src/views/design/sidemenu/editsecmenu/index.jsx
index ad44fad..57e0cff 100644
--- a/src/views/design/sidemenu/editsecmenu/index.jsx
+++ b/src/views/design/sidemenu/editsecmenu/index.jsx
@@ -126,6 +126,7 @@
         onOk() {
           return Api.getSystemConfig(param).then(res => {
             if (res.status) {
+              that.setState({ change: false })
               MKEmitter.emit('mkUpdateMenuList')
             } else {
               notification.warning({
diff --git a/src/views/design/sidemenu/editthdmenu/index.jsx b/src/views/design/sidemenu/editthdmenu/index.jsx
index 4da6159..7b575a2 100644
--- a/src/views/design/sidemenu/editthdmenu/index.jsx
+++ b/src/views/design/sidemenu/editthdmenu/index.jsx
@@ -157,6 +157,7 @@
         onOk() {
           return Api.getSystemConfig(param).then(res => {
             if (res.status) {
+              that.setState({ change: false })
               MKEmitter.emit('mkUpdateMenuList')
             } else {
               notification.warning({
diff --git a/src/views/main/index.jsx b/src/views/main/index.jsx
index 8dd7821..3fa342e 100644
--- a/src/views/main/index.jsx
+++ b/src/views/main/index.jsx
@@ -17,7 +17,15 @@
 const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 
 class Main extends Component {
-  state = {}
+  state = {
+    userId: sessionStorage.getItem('UserID')
+  }
+
+  UNSAFE_componentWillMount() {
+    if (!this.state.userId) {
+      this.props.history.replace('/login')
+    }
+  }
 
   componentDidMount () {
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -50,7 +58,9 @@
 
   render () {
     const navBar = window.GLOB.navBar
-    
+
+    if (!this.state.userId) return null
+
     return (
       <div className="mk-main-view">
         <ConfigProvider locale={_locale}>
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index e816b50..57e7d08 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -805,8 +805,14 @@
     })
 
     setTimeout(() => {
-      if (config.enabled && this.verifyConfig()) {
+      let _pass = this.verifyConfig(config)
+
+      if (config.enabled && !_pass) {
         config.enabled = false
+        config.force = true
+      } else if (!config.enabled && config.force && _pass) {
+        config.enabled = true
+        delete config.force
       }
 
       if (config.cacheUseful !== 'true') {
@@ -1030,17 +1036,23 @@
   onEnabledChange = () => {
     const { config } = this.state
 
-    if (!config || (!config.enabled && this.verifyConfig(true))) {
-      return
-    }
+    let _config = {...config, enabled: !config.enabled}
 
-    this.setState({
-      config: {...config, enabled: !config.enabled}
-    })
+    delete _config.force
+
+    if (!_config.enabled) {
+      this.setState({
+        config: _config
+      })
+    } else if (this.verifyConfig(_config)) {
+      this.setState({
+        config: _config
+      })
+    }
   }
 
-  verifyConfig = (show) => {
-    const { config, MenuType } = this.state
+  verifyConfig = (config) => {
+    const { MenuType } = this.state
     let error = ''
 
     let check = (components) => {
@@ -1068,7 +1080,7 @@
 
     check(config.components)
 
-    if (show && error) {
+    if (config.enabled && error) {
       notification.warning({
         top: 92,
         message: error,
@@ -1102,7 +1114,7 @@
         }
       })
 
-      if (show && error) {
+      if (config.enabled && error) {
         notification.warning({
           top: 92,
           message: error,
@@ -1111,7 +1123,7 @@
       }
     }
 
-    return error
+    return error === ''
   }
 
   // 鏇存柊閰嶇疆淇℃伅
@@ -1226,7 +1238,7 @@
                     <PictureController/>
                     <StyleCombControlButton menu={config} />
                     <PasteController insert={this.insert} />
-                    <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config && config.enabled} onChange={this.onEnabledChange} />
+                    {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                     <Button type="primary" id="save-config" className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
                     <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
                   </div>
diff --git a/src/views/menudesign/popview/index.jsx b/src/views/menudesign/popview/index.jsx
index 7e63303..8a783ea 100644
--- a/src/views/menudesign/popview/index.jsx
+++ b/src/views/menudesign/popview/index.jsx
@@ -130,8 +130,14 @@
       return
     }
 
-    if (config.enabled && this.verifyConfig()) {
+    let _pass = this.verifyConfig(config)
+
+    if (config.enabled && !_pass) {
       config.enabled = false
+      config.force = true
+    } else if (!config.enabled && config.force && _pass) {
+      config.enabled = true
+      delete config.force
     }
 
     this.getMenuMessage(config)
@@ -149,17 +155,22 @@
   onEnabledChange = () => {
     const { config } = this.state
 
-    if (!config.enabled && this.verifyConfig(true)) {
-      return
-    }
+    let _config = {...config, enabled: !config.enabled}
 
-    this.setState({
-      config: {...config, enabled: !config.enabled}
-    })
+    delete _config.force
+
+    if (!_config.enabled) {
+      this.setState({
+        config: _config
+      })
+    } else if (this.verifyConfig(_config)) {
+      this.setState({
+        config: _config
+      })
+    }
   }
 
-  verifyConfig = (show) => {
-    const { config } = this.state
+  verifyConfig = (config) => {
     let error = ''
 
     let check = (components) => {
@@ -186,7 +197,7 @@
 
     check(config.components)
 
-    if (show && error) {
+    if (config.enabled && error) {
       notification.warning({
         top: 92,
         message: error,
@@ -194,7 +205,7 @@
       })
     }
 
-    return error
+    return error === ''
   }
 
   // 鏇存柊閰嶇疆淇℃伅
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index dc5675f..1504072 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -1384,8 +1384,14 @@
     })
 
     setTimeout(() => {
-      if (config.enabled && this.verifyConfig()) {
+      let _pass = this.verifyConfig(config)
+
+      if (config.enabled && !_pass) {
         config.enabled = false
+        config.force = true
+      } else if (!config.enabled && config.force && _pass) {
+        config.enabled = true
+        delete config.force
       }
 
       if (config.cacheUseful !== 'true') {
@@ -1713,17 +1719,22 @@
   onEnabledChange = () => {
     const { config } = this.state
 
-    if (!config || (!config.enabled && this.verifyConfig(true))) {
-      return
-    }
+    let _config = {...config, enabled: !config.enabled}
 
-    this.setState({
-      config: {...config, enabled: !config.enabled}
-    })
+    delete _config.force
+
+    if (!_config.enabled) {
+      this.setState({
+        config: _config
+      })
+    } else if (this.verifyConfig(_config)) {
+      this.setState({
+        config: _config
+      })
+    }
   }
 
-  verifyConfig = (show) => {
-    const { config } = this.state
+  verifyConfig = (config) => {
     let error = ''
     let searchSum = 0
     let swipes = []
@@ -1790,7 +1801,7 @@
       }
     }
 
-    if (show && error) {
+    if (config.enabled && error) {
       notification.warning({
         top: 92,
         message: error,
@@ -1798,7 +1809,7 @@
       })
     }
 
-    return error
+    return error === ''
   }
 
   // 鏇存柊閰嶇疆淇℃伅
@@ -2091,7 +2102,7 @@
               </div>
               <div className="wrap">
                 <Button type="primary" className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
-                <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config && config.enabled} onChange={this.onEnabledChange} />
+                {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                 <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
                 <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
                 <CreateView resetmenu={this.getAppMenus} />
diff --git a/src/views/mobdesign/popview/index.jsx b/src/views/mobdesign/popview/index.jsx
index 316deca..03cfee3 100644
--- a/src/views/mobdesign/popview/index.jsx
+++ b/src/views/mobdesign/popview/index.jsx
@@ -132,8 +132,14 @@
       return
     }
 
-    if (config.enabled && this.verifyConfig()) {
+    let _pass = this.verifyConfig(config)
+
+    if (config.enabled && !_pass) {
       config.enabled = false
+      config.force = true
+    } else if (!config.enabled && config.force && _pass) {
+      config.enabled = true
+      delete config.force
     }
 
     this.getMenuMessage(config)
@@ -151,17 +157,22 @@
   onEnabledChange = () => {
     const { config } = this.state
 
-    if (!config.enabled && this.verifyConfig(true)) {
-      return
-    }
+    let _config = {...config, enabled: !config.enabled}
 
-    this.setState({
-      config: {...config, enabled: !config.enabled}
-    })
+    delete _config.force
+
+    if (!_config.enabled) {
+      this.setState({
+        config: _config
+      })
+    } else if (this.verifyConfig(_config)) {
+      this.setState({
+        config: _config
+      })
+    }
   }
 
-  verifyConfig = (show) => {
-    const { config } = this.state
+  verifyConfig = (config) => {
     let error = ''
 
     let check = (components) => {
@@ -188,7 +199,7 @@
 
     check(config.components)
 
-    if (show && error) {
+    if (config.enabled && error) {
       notification.warning({
         top: 92,
         message: error,
@@ -196,7 +207,7 @@
       })
     }
 
-    return error
+    return error === ''
   }
 
   // 鏇存柊閰嶇疆淇℃伅
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index 1f071f1..b6b2760 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -1125,8 +1125,14 @@
     })
 
     setTimeout(() => {
-      if (config.enabled && this.verifyConfig()) {
+      let _pass = this.verifyConfig(config)
+
+      if (config.enabled && !_pass) {
         config.enabled = false
+        config.force = true
+      } else if (!config.enabled && config.force && _pass) {
+        config.enabled = true
+        delete config.force
       }
 
       if (config.cacheUseful !== 'true') {
@@ -1435,17 +1441,22 @@
   onEnabledChange = () => {
     const { config } = this.state
 
-    if (!config || (!config.enabled && this.verifyConfig(true))) {
-      return
-    }
+    let _config = {...config, enabled: !config.enabled}
 
-    this.setState({
-      config: {...config, enabled: !config.enabled}
-    })
+    delete _config.force
+
+    if (!_config.enabled) {
+      this.setState({
+        config: _config
+      })
+    } else if (this.verifyConfig(_config)) {
+      this.setState({
+        config: _config
+      })
+    }
   }
 
-  verifyConfig = (show) => {
-    const { config } = this.state
+  verifyConfig = (config) => {
     let error = ''
 
     let check = (components) => {
@@ -1472,7 +1483,7 @@
 
     check(config.components)
 
-    if (show && error) {
+    if (config.enabled && error) {
       notification.warning({
         top: 92,
         message: error,
@@ -1480,7 +1491,7 @@
       })
     }
 
-    return error
+    return error === ''
   }
 
   // 鏇存柊閰嶇疆淇℃伅
@@ -1707,7 +1718,7 @@
               </div>
               <div className="wrap">
                 <Button type="primary" className={needUpdate ? 'update-tip' : ''} id="save-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config && config.enabled} onChange={this.onEnabledChange} />
+                {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                 <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
                 <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
                 <CreateView resetmenu={this.getAppMenus} />
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index 0689387..18311e8 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -518,8 +518,14 @@
     })
 
     setTimeout(() => {
-      if (config.enabled && this.verifyConfig()) {
+      let _pass = this.verifyConfig(config)
+
+      if (config.enabled && !_pass) {
         config.enabled = false
+        config.force = true
+      } else if (!config.enabled && config.force && _pass) {
+        config.enabled = true
+        delete config.force
       }
 
       let tbs = []
@@ -681,17 +687,22 @@
   onEnabledChange = () => {
     const { config } = this.state
 
-    if (!config || (!config.enabled && this.verifyConfig(true))) {
-      return
-    }
+    let _config = {...config, enabled: !config.enabled}
 
-    this.setState({
-      config: {...config, enabled: !config.enabled}
-    })
+    delete _config.force
+
+    if (!_config.enabled) {
+      this.setState({
+        config: _config
+      })
+    } else if (this.verifyConfig(_config)) {
+      this.setState({
+        config: _config
+      })
+    }
   }
 
-  verifyConfig = (show) => {
-    const { config } = this.state
+  verifyConfig = (config) => {
     let error = ''
 
     config.components.forEach(item => {
@@ -725,7 +736,7 @@
       }
     }
 
-    if (show && error) {
+    if (config.enabled && error) {
       notification.warning({
         top: 92,
         message: error,
@@ -733,7 +744,7 @@
       })
     }
 
-    return error
+    return error === ''
   }
 
   // 鏇存柊閰嶇疆淇℃伅
@@ -843,7 +854,7 @@
                     <TableNodes config={config} />
                     <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                     <PasteBaseTable type="page" insert={this.insert}/>
-                    <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config && config.enabled} onChange={this.onEnabledChange} />
+                    {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                     <Button type="primary" id="save-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
                     <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
                   </div>

--
Gitblit v1.8.0