From 474c68f0fea10cc62977c67d186732b3346cdd53 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 17 一月 2023 18:04:45 +0800
Subject: [PATCH] 2023-01-17

---
 src/templates/zshare/modalform/index.jsx                                          |    6 
 src/utils/utils-datamanage.js                                                     |    3 
 src/tabviews/custom/components/code/sand-box/index.jsx                            |   43 +
 src/menu/components/group/paste/index.jsx                                         |    4 
 src/tabviews/custom/components/tree/antd-tree/index.jsx                           |   26 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                            |    2 
 src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx                    |    2 
 src/tabviews/custom/components/carousel/prop-card/index.scss                      |    4 
 src/tabviews/custom/popview/index.jsx                                             |   26 
 src/tabviews/basetable/index.jsx                                                  |    2 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx |    6 
 src/menu/components/tree/antd-tree/index.jsx                                      |    2 
 src/menu/components/table/edit-table/columns/editColumn/index.jsx                 |    6 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx              |    6 
 src/templates/zshare/editTable/index.scss                                         |    3 
 src/tabviews/zshare/actionList/changeuserbutton/index.jsx                         |    5 
 src/tabviews/custom/components/card/data-card/index.jsx                           |   38 +
 src/tabviews/custom/components/card/prop-card/index.jsx                           |   28 
 src/api/cacheutils.js                                                             |  116 +++
 src/tabviews/custom/components/module/voucher/index.jsx                           |   45 +
 src/tabviews/custom/components/group/normal-group/index.jsx                       |   15 
 src/tabviews/custom/components/table/normal-table/index.jsx                       |   66 ++
 src/tabviews/custom/components/chart/antv-pie/index.jsx                           |   85 +-
 src/tabviews/custom/components/timeline/normal-timeline/index.jsx                 |   25 
 src/menu/pastecontroller/index.jsx                                                |    4 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx             |   10 
 src/tabviews/zshare/mutilform/index.jsx                                           |   11 
 src/tabviews/custom/components/carousel/prop-card/index.jsx                       |   28 
 src/tabviews/custom/index.jsx                                                     |   27 
 src/views/appmanage/submutilform/index.jsx                                        |    2 
 src/menu/components/tabs/paste/index.jsx                                          |    4 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx                 |    6 
 src/tabviews/custom/components/chart/antv-scatter/index.jsx                       |   79 +-
 src/tabviews/custom/components/chart/antv-bar-line/index.jsx                      |   73 +-
 src/tabviews/custom/components/table/base-table/index.jsx                         |   19 
 package-lock.json                                                                 |   51 +
 src/tabviews/custom/components/chart/antv-dashboard/index.jsx                     |  150 ++--
 src/tabviews/custom/components/card/balcony/index.scss                            |    4 
 src/components/header/index.jsx                                                   |    1 
 src/tabviews/zshare/topSearch/index.jsx                                           |   11 
 src/tabviews/custom/components/chart/antv-G6/index.jsx                            |  128 ++-
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                           |   22 
 src/tabviews/custom/components/carousel/data-card/index.jsx                       |   27 
 src/tabviews/custom/components/table/edit-table/index.jsx                         |    2 
 src/api/index.js                                                                  |   61 +
 src/tabviews/custom/components/share/normalTable/index.jsx                        |    9 
 src/tabviews/custom/components/chart/custom-chart/index.jsx                       |   78 +-
 src/utils/utils.js                                                                |   18 
 src/tabviews/custom/components/card/table-card/index.scss                         |    4 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx             |   53 +
 src/tabviews/custom/components/card/prop-card/index.scss                          |    4 
 src/tabviews/custom/components/card/table-card/index.jsx                          |   28 
 src/tabviews/custom/components/timeline/normal-timeline/index.scss                |    4 
 src/tabviews/custom/components/share/tabtransfer/index.jsx                        |   15 
 src/menu/stylecontroller/index.jsx                                                |   20 
 src/menu/datasource/verifycard/settingform/index.jsx                              |    5 
 src/tabviews/custom/components/module/voucher/voucherTable/index.scss             |   23 
 src/menu/components/card/cardsimplecomponent/index.jsx                            |   56 
 src/tabviews/custom/components/module/voucher/voucherTable/index.jsx              |  133 +++-
 src/tabviews/custom/components/card/balcony/index.jsx                             |   28 
 package.json                                                                      |    1 
 src/views/login/index.jsx                                                         |   14 
 62 files changed, 1,350 insertions(+), 427 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 380e9ac..a469c79 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19343,6 +19343,52 @@
       "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
       "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
     },
+    "sheetjs-style": {
+      "version": "0.15.8",
+      "resolved": "https://registry.npmjs.org/sheetjs-style/-/sheetjs-style-0.15.8.tgz",
+      "integrity": "sha512-/wRiwnq5ck7aO+zLBs+u5JqQK4agUTIGCS0nxgaMjFl6XdlVaaB/RNJcP6S6Efj3+RYbSZuAoyqmSnbzxfT7Kg==",
+      "requires": {
+        "adler-32": "~1.2.0",
+        "cfb": "^1.1.4",
+        "codepage": "~1.14.0",
+        "commander": "~2.17.1",
+        "crc-32": "~1.2.0",
+        "exit-on-epipe": "~1.0.1",
+        "ssf": "~0.10.3",
+        "wmf": "~1.0.1"
+      },
+      "dependencies": {
+        "cfb": {
+          "version": "1.2.2",
+          "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
+          "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+          "requires": {
+            "adler-32": "~1.3.0",
+            "crc-32": "~1.2.0"
+          },
+          "dependencies": {
+            "adler-32": {
+              "version": "1.3.1",
+              "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+              "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
+            }
+          }
+        },
+        "commander": {
+          "version": "2.17.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+          "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
+        },
+        "ssf": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.3.tgz",
+          "integrity": "sha512-pRuUdW0WwyB2doSqqjWyzwCD6PkfxpHAHdZp39K3dp/Hq7f+xfMwNAWIi16DyrRg4gg9c/RvLYkJTSawTPTm1w==",
+          "requires": {
+            "frac": "~1.1.2"
+          }
+        }
+      }
+    },
     "shell-quote": {
       "version": "1.6.1",
       "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
@@ -21720,6 +21766,11 @@
         "string-width": "^1.0.2 || 2 || 3 || 4"
       }
     },
+    "wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
+    },
     "wolfy87-eventemitter": {
       "version": "5.2.9",
       "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz",
diff --git a/package.json b/package.json
index 8963e6d..5ae1493 100644
--- a/package.json
+++ b/package.json
@@ -95,6 +95,7 @@
     "resolve-url-loader": "3.1.0",
     "sass-loader": "7.2.0",
     "semver": "6.3.0",
+    "sheetjs-style": "^0.15.8",
     "spark-md5": "^3.0.1",
     "sql-formatter": "^11.0.2",
     "style-loader": "1.0.0",
diff --git a/src/api/cacheutils.js b/src/api/cacheutils.js
index 542bfde..012223d 100644
--- a/src/api/cacheutils.js
+++ b/src/api/cacheutils.js
@@ -22,6 +22,13 @@
           throw 'CREATE TABLE ERROR'
         })
 
+        tx.executeSql('CREATE TABLE IF NOT EXISTS CACHES (menuid varchar(50), CreateDate varchar(50), LongParam text, CDefine1 varchar(50), CDefine2 varchar(50))', [], () => {
+
+        }, () => {
+          // eslint-disable-next-line
+          throw 'CREATE TABLE ERROR'
+        })
+
         if (window.GLOB.systemType === '') {
           tx.executeSql('CREATE TABLE IF NOT EXISTS FUNCS (func_code varchar(50), key_sql text, CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50))', [], () => {
 
@@ -217,11 +224,55 @@
   }
 
   /**
+   * @description 灏嗙紦瀛樻暟鎹啓鍏ebsql
+   */
+  static writeCacheInWebSql (data) {
+    if (!window.GLOB.WebSql) return
+    window.GLOB.WebSql.transaction(tx => {
+      tx.executeSql(`DELETE FROM CACHES where menuid='${data[0]}'`)
+      if (data[2]) {
+        tx.executeSql('INSERT INTO CACHES (menuid, CreateDate, LongParam) VALUES (?, ?, ?)', data)
+      }
+    })
+  }
+
+  /**
+   * @description 鑾峰彇websql涓殑閰嶇疆淇℃伅
+   */
+  static getWebSqlCacheConfig (MenuID) {
+    if (!window.GLOB.WebSql) return Promise.resolve()
+    return new Promise((resolve, reject) => {
+      window.GLOB.WebSql.transaction(tx => {
+        tx.executeSql(`SELECT * FROM CACHES WHERE menuid='${MenuID}'`, [], (tx, results) => {
+          resolve(results.rows[0])
+        }, (tx, results) => {
+          console.warn(results)
+          resolve()
+        })
+      })
+    })
+  }
+
+  /**
+   * @description 鍒犻櫎websql涓秴杩�7澶╃殑缂撳瓨淇℃伅
+   */
+  static delWebSqlCacheConfig (date, type) {
+    if (!window.GLOB.WebSql) return
+    window.GLOB.WebSql.transaction(tx => {
+      if (type === 'all') {
+        tx.executeSql('DELETE FROM CACHES')
+      } else {
+        tx.executeSql(`DELETE FROM CACHES where CreateDate<'${date}'`)
+      }
+    })
+  }
+
+  /**
    * @description 鎵撳紑IndexedDB
    */
   static openIndexDB (db) {
     try {
-      let request = window.indexedDB.open(db, 1)
+      let request = window.indexedDB.open(db, 2)
       request.onerror = () => {
         console.warn('IndexedDB 鍒濆鍖栧け璐ワ紒')
       }
@@ -237,6 +288,9 @@
           let objectStore = window.GLOB.IndexDB.createObjectStore('configs', { keyPath: 'id' })
           objectStore.createIndex('menuid', 'menuid', { unique: false })
           objectStore.createIndex('userid', 'userid', { unique: false })
+        }
+        if (!window.GLOB.IndexDB.objectStoreNames.contains('caches')) {
+          window.GLOB.IndexDB.createObjectStore('caches', { keyPath: 'menuid' })
         }
         if (window.GLOB.systemType === '' && !window.GLOB.IndexDB.objectStoreNames.contains('funcs')) {
           window.GLOB.IndexDB.createObjectStore('funcs', { keyPath: 'id' })
@@ -440,12 +494,62 @@
   static writeInIndexDB (data) {
     if (!window.GLOB.IndexDB || !data) return
 
-    let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite')
-      .objectStore('configs')
-      .add(data)
+    window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs').add(data)
+  }
 
-    request.onerror = () => {
-      window.GLOB.IndexDB = null
+  /**
+   * @description 灏嗘暟鎹啓鍏ndexedDB
+   */
+  static writeCacheInIndexDB (data) {
+    if (!window.GLOB.IndexDB) return
+
+    let objectStore = window.GLOB.IndexDB.transaction(['caches'], 'readwrite').objectStore('caches')
+    objectStore.delete(data.menuid)
+
+    if (data.LongParam) {
+      objectStore.add(data)
+    }
+  }
+
+  /**
+   * @description 鑾峰彇IndexedDB涓殑閰嶇疆淇℃伅
+   */
+  static getIndexDBCacheConfig (MenuID) {
+    if (!window.GLOB.IndexDB) return Promise.resolve()
+    
+    return new Promise((resolve, reject) => {
+      let request = window.GLOB.IndexDB.transaction(['caches']).objectStore('caches').get(MenuID)
+
+      request.onerror = () => {
+        resolve()
+      }
+
+      request.onsuccess = () => {
+        resolve(request.result)
+      }
+    })
+  }
+
+  /**
+   * @description 鍒犻櫎IndexedDB涓秴杩�7澶╃殑缂撳瓨淇℃伅
+   */
+  static delIndexDBCacheConfig (date, type) {
+    if (!window.GLOB.IndexDB) return
+
+    if (type === 'all') {
+      window.GLOB.IndexDB.transaction(['caches'], 'readwrite').objectStore('caches').clear()
+    } else {
+      let request = window.GLOB.IndexDB.transaction(['caches'], 'readwrite').objectStore('caches').openCursor()
+  
+      request.onsuccess = (e) => {
+        let cursor = e.target.result
+        if (cursor) {
+          if (cursor.value.CreateDate < date) {
+            cursor.delete()
+          }
+          cursor.continue()
+        }
+      }
     }
   }
 }
\ No newline at end of file
diff --git a/src/api/index.js b/src/api/index.js
index aeead48..6d8e820 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -264,7 +264,7 @@
   /**
    * @description 鎵嬫満鍙烽獙璇佺爜鐧诲綍
    */
-  getphoneusermsg (phoneNo, checkcode, isCloud = false, ipAddress, city) {
+  getphoneusermsg (phoneNo, checkcode, isCloud = false) {
     let param = {
       // func: 'webapi_login',
       mob: phoneNo,
@@ -273,8 +273,8 @@
       check_code: checkcode,
       way_no: 'sms_vcode',
       systemType: options.sysType,
-      login_city: city,
-      login_id_address: ipAddress,
+      login_city: sessionStorage.getItem('city') || '',
+      login_id_address: sessionStorage.getItem('ipAddress') || '',
       kei_id: window.btoa(window.encodeURIComponent(window.GLOB.host)),
       device_id: localStorage.getItem('SessionUid'),
       appkey: window.GLOB.appkey || ''
@@ -303,14 +303,14 @@
   /**
    * @description 鐧诲綍绯荤粺, 鑾峰彇鐢ㄦ埛淇℃伅
    */
-  getusermsg (username, password, isCloud = false, ipAddress, city) {
+  getusermsg (username, password, isCloud = false) {
     let param = {
       // func: 'webapi_login',
       UserName: username,
       systemType: options.sysType,
       Type: 'S',
-      login_city: city,
-      login_id_address: ipAddress,
+      login_city: sessionStorage.getItem('city') || '',
+      login_id_address: sessionStorage.getItem('ipAddress') || '',
       kei_id: window.btoa(window.encodeURIComponent(window.GLOB.host)),
       device_id: localStorage.getItem('SessionUid'),
       timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
@@ -366,6 +366,55 @@
     })
   }
 
+  delCacheConfig (type = '') {
+    let date = moment().subtract(7, 'days').format('YYYY-MM-DD')
+    CacheUtils.delWebSqlCacheConfig(date, type)
+    CacheUtils.delIndexDBCacheConfig(date, type)
+  }
+
+  writeCacheConfig (menuid, data) {
+    if (!menuid) return
+    let date = moment().format('YYYY-MM-DD')
+    let _data = data ? JSON.stringify(data) : ''
+
+    CacheUtils.writeCacheInWebSql([menuid, date, _data])
+    CacheUtils.writeCacheInIndexDB({menuid, CreateDate: date, LongParam: _data})
+  }
+
+  getLCacheConfig (menuid) {
+    return new Promise((resolve, reject) => {
+      if (window.GLOB.WebSql) {
+        CacheUtils.getWebSqlCacheConfig(menuid).then(res => {
+          if (res && res.LongParam) {
+            let _data = JSON.parse(res.LongParam)
+            if (_data.length === 0) {
+              resolve()
+            } else {
+              resolve(_data)
+            }
+          } else {
+            resolve()
+          }
+        })
+      } else if (window.GLOB.IndexDB) {
+        CacheUtils.getIndexDBCacheConfig(menuid).then(res => {
+          if (res && res.LongParam) {
+            let _data = JSON.parse(res.LongParam)
+            if (_data.length === 0) {
+              resolve()
+            } else {
+              resolve(_data)
+            }
+          } else {
+            resolve()
+          }
+        })
+      } else {
+        resolve()
+      }
+    })
+  }
+
   /**
    * @description 鐧诲綍浜屾楠岃瘉 // positecgroup
    */
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 4ac4fbd..7f2669a 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -558,6 +558,7 @@
             resolve()
           } else {
             Api.updateAppVersion()
+            Api.delCacheConfig('all')
             setTimeout(() => {
               notification.success({
                 top: 92,
diff --git a/src/menu/components/card/cardsimplecomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
index 1edd5d7..cf6e1d3 100644
--- a/src/menu/components/card/cardsimplecomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -212,7 +212,7 @@
     let _style = {...card.style}
 
     if (cards.type === 'carousel') {
-      _style.height = cards.style.height
+      _style.height = cards.wrap.height
     }
 
     let control = true
@@ -223,34 +223,32 @@
     _style = resetStyle(_style)
 
     return (
-      <div className="ant-col ant-col-24">
-        <div className="card-item" style={_style}>
-          <CardCellComponent cards={cards} cardCell={card} elements={card.elements} updateElement={this.updateCard}/>
-          <div className="card-control">
-            <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-              <div className="mk-popover-control">
-                <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement}/>
-                <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/>
-                {cards.type !== 'timeline' ? <NormalForm title="鍗$墖璁剧疆" width={800} update={this.updateSetting} getForms={this.getSettingForms}>
-                  <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
-                </NormalForm> : <NodesWrap card={card} updateMenus={this.updateNodes}/>}
-                {cards.type !== 'timeline' ? <CopyComponent type="cardcell" card={card}/> : null}
-                <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} />
-                <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-                {control ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-                  <div className="mk-popover-control">
-                    <ArrowLeftOutlined className="plus" title="鍓嶇Щ" onClick={() => this.props.move(card, 'left')} />
-                    <ArrowRightOutlined className="close" title="鍚庣Щ" onClick={() => this.props.move(card, 'right')} />
-                  </div>
-                } trigger="hover" getPopupContainer={() => document.getElementById(card.uuid + 'swap')}>
-                  <SwapOutlined id={card.uuid + 'swap'}/>
-                </Popover> : null}
-                {control ? <DeleteOutlined className="close" title="鍒犻櫎鍗$墖" onClick={() => this.props.deleteElement(card)} /> : null}
-              </div>
-            } trigger="hover">
-              <ToolOutlined/>
-            </Popover>
-          </div>
+      <div className="card-item" style={_style}>
+        <CardCellComponent cards={cards} cardCell={card} elements={card.elements} updateElement={this.updateCard}/>
+        <div className="card-control">
+          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+            <div className="mk-popover-control">
+              <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement}/>
+              <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/>
+              {cards.type !== 'timeline' ? <NormalForm title="鍗$墖璁剧疆" width={800} update={this.updateSetting} getForms={this.getSettingForms}>
+                <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
+              </NormalForm> : <NodesWrap card={card} updateMenus={this.updateNodes}/>}
+              {cards.type !== 'timeline' ? <CopyComponent type="cardcell" card={card}/> : null}
+              <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} />
+              <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
+              {control ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+                <div className="mk-popover-control">
+                  <ArrowLeftOutlined className="plus" title="鍓嶇Щ" onClick={() => this.props.move(card, 'left')} />
+                  <ArrowRightOutlined className="close" title="鍚庣Щ" onClick={() => this.props.move(card, 'right')} />
+                </div>
+              } trigger="hover" getPopupContainer={() => document.getElementById(card.uuid + 'swap')}>
+                <SwapOutlined id={card.uuid + 'swap'}/>
+              </Popover> : null}
+              {control ? <DeleteOutlined className="close" title="鍒犻櫎鍗$墖" onClick={() => this.props.deleteElement(card)} /> : null}
+            </div>
+          } trigger="hover">
+            <ToolOutlined/>
+          </Popover>
         </div>
       </div>
     )
diff --git a/src/menu/components/group/paste/index.jsx b/src/menu/components/group/paste/index.jsx
index 755b6f3..05b5104 100644
--- a/src/menu/components/group/paste/index.jsx
+++ b/src/menu/components/group/paste/index.jsx
@@ -24,7 +24,7 @@
 
   pasteSubmit = () => {
     let appType = sessionStorage.getItem('appType')
-    let options = ['datacard', 'propcard', 'balcony', 'timeline', 'simpleform', 'stepform', 'tabform', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart', 'sandbox']
+    let options = ['datacard', 'propcard', 'balcony', 'timeline', 'simpleform', 'stepform', 'tabform', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'scatter', 'sandbox']
     let types = {
       login: '鐧诲綍',
       navbar: '瀵艰埅鏍�',
@@ -37,7 +37,7 @@
     }
 
     if (appType !== 'mob') {
-      options.push('editable', 'antvG6')
+      options.push('editable', 'antvG6', 'tree', 'dashboard', 'chart')
     }
 
     this.pasteFormRef.handleConfirm().then(res => {
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 1fac697..88c227d 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -214,7 +214,11 @@
 
     let resource = this.props.form.getFieldValue('dataSource') || ''
 
-    resource = `select '' as ${field},'鍏ㄩ儴' as ${text} union all \n${resource}`
+    if (field === text) {
+      resource = `select '' as ${field} union all \n${resource}`
+    } else {
+      resource = `select '' as ${field},'鍏ㄩ儴' as ${text} union all \n${resource}`
+    }
 
     this.props.form.setFieldsValue({dataSource: resource})
   }
diff --git a/src/menu/components/tabs/paste/index.jsx b/src/menu/components/tabs/paste/index.jsx
index 9a398fa..53b2285 100644
--- a/src/menu/components/tabs/paste/index.jsx
+++ b/src/menu/components/tabs/paste/index.jsx
@@ -60,7 +60,7 @@
   pasteSubmit = () => {
     const { Tab } = this.props
     let appType = sessionStorage.getItem('appType')
-    let options = ['tabs', 'group', 'datacard', 'propcard', 'timeline', 'balcony', 'normaltable', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart', 'sandbox']
+    let options = ['tabs', 'group', 'datacard', 'propcard', 'timeline', 'balcony', 'normaltable', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'tablecard', 'line', 'bar', 'pie', 'scatter', 'sandbox']
     let types = {
       login: '鐧诲綍',
       navbar: '瀵艰埅鏍�',
@@ -70,7 +70,7 @@
     if (appType === 'mob') {
       options.push('menubar')
     } else {
-      options.push('editable', 'antvG6')
+      options.push('editable', 'antvG6', 'tree', 'dashboard', 'chart')
     }
 
     this.pasteFormRef.handleConfirm().then(res => {
diff --git a/src/menu/components/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx
index 3dd7abd..c3c8640 100644
--- a/src/menu/components/tree/antd-tree/index.jsx
+++ b/src/menu/components/tree/antd-tree/index.jsx
@@ -173,7 +173,7 @@
             <NormalForm title="鍩烘湰璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
-            <CopyComponent type="normaltable" card={card}/>
+            <CopyComponent type="tree" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
             <UserComponent config={card}/>
diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx
index 419b015..ad9a2bd 100644
--- a/src/menu/datasource/verifycard/settingform/index.jsx
+++ b/src/menu/datasource/verifycard/settingform/index.jsx
@@ -86,12 +86,17 @@
   }
 
   handleConfirm = () => {
+    const { config } = this.props
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
           values.sync = values.sync || 'false'
 
+          if (['navbar', 'balcony', 'menubar', 'interface'].includes(config.type)) {
+            values.onload = 'true'
+          }
+
           // 鏁版嵁婧愬墠绔獙璇�
           if (values.interType === 'system' && values.execute !== 'false' && values.dataresource) {
             let _quot = values.dataresource.match(/'{1}/g)
diff --git a/src/menu/pastecontroller/index.jsx b/src/menu/pastecontroller/index.jsx
index 5c6dcd7..7a49bf2 100644
--- a/src/menu/pastecontroller/index.jsx
+++ b/src/menu/pastecontroller/index.jsx
@@ -59,7 +59,7 @@
 
   pasteSubmit = () => {
     let appType = sessionStorage.getItem('appType')
-    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'iframe', 'sandbox']
+    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'scatter', 'iframe', 'sandbox']
 
     if (appType === 'mob') {
       if (sessionStorage.getItem('editMenuType') !== 'popview') {
@@ -68,7 +68,7 @@
         options.push('menubar')
       }
     } else {
-      options.push('editable', 'antvG6')
+      options.push('editable', 'antvG6', 'tree', 'dashboard', 'chart')
     }
 
     this.pasteFormRef.handleConfirm().then(res => {
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index 80cde31..053ee15 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -98,13 +98,27 @@
     }
 
     this.callback = callback
+    let card = fromJS(style).toJS()
+    let borposition = 'outer'
+
+    if (!card.borderWidth) {
+      if (card.borderLeftWidth) {
+        borposition = 'left'
+      } else if (card.borderRightWidth) {
+        borposition = 'right'
+      } else if (card.borderTopWidth) {
+        borposition = 'top'
+      } else if (card.borderBottomWidth) {
+        borposition = 'bottom'
+      }
+    }
 
     this.setState({
       visible: true,
       fonts: fonts,
-      card: fromJS(style).toJS(),
+      card: card,
       options: options,
-      borposition: 'outer',
+      borposition: borposition,
       backgroundImage
     })
     window.GLOB.styling = true
@@ -674,7 +688,7 @@
                     label={<BorderOutlined title="杈规浣嶇疆"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <Radio.Group className="border-position" defaultValue={'outer'} onChange={(e) => this.setState({borposition: e.target.value})}>
+                    <Radio.Group className="border-position" defaultValue={borposition} onChange={(e) => this.setState({borposition: e.target.value})}>
                       <Radio value="outer"><BorderOuterOutlined title="澶栬竟妗�"/></Radio>
                       <Radio value="left"><BorderLeftOutlined title="宸﹁竟妗�"/></Radio>
                       <Radio value="right"><BorderRightOutlined title="鍙宠竟妗�"/></Radio>
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index 7923571..7965a78 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -291,6 +291,8 @@
         })
 
         return true
+      } else {
+        item.name = (this.props.MenuName || '')
       }
 
       // 鎼滅储鏉′欢鍒濆鍖�
diff --git a/src/tabviews/custom/components/card/balcony/index.jsx b/src/tabviews/custom/components/card/balcony/index.jsx
index dde04a1..bf037dd 100644
--- a/src/tabviews/custom/components/card/balcony/index.jsx
+++ b/src/tabviews/custom/components/card/balcony/index.jsx
@@ -31,6 +31,8 @@
     checked: false
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { data, initdata } = this.props
     let _config = fromJS(this.props.config).toJS()
@@ -59,16 +61,21 @@
           _data = _data[0] || {$$empty: true}
         }
         _sync = false
+        this.loaded = true
       } else if (_sync && initdata) {
         _data = initdata
         if (Array.isArray(_data)) {
           _data = _data[0] || {$$empty: true}
         }
         _sync = false
+        this.loaded = true
       }
     } else if (_config.wrap.datatype === 'public' && window.GLOB.CacheData.get(_config.wrap.publicId)) {
       _data = window.GLOB.CacheData.get(_config.wrap.publicId)
       _data = fromJS(_data).toJS()
+      this.loaded = true
+    } else if (_config.wrap.datatype === 'static') {
+      this.loaded = true
     }
 
     _data.$$BID = BID || ''
@@ -143,6 +150,17 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {this.loadData(true)})
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        let _data = res[0]
+        _data.$$uuid = _data[config.setting.primaryKey] || ''
+
+        this.setState({data: _data})
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -182,6 +200,8 @@
       _data.$$BData = BData || ''
       _data.$$uuid = _data[config.setting.primaryKey] || ''
 
+      this.loaded = true
+
       this.setState({sync: false, data: _data})
     }
   }
@@ -195,6 +215,8 @@
       _data.$$BID = BID || ''
       _data.$$BData = BData || ''
       _data.$$uuid = _data[config.setting.primaryKey] || ''
+
+      this.loaded = true
 
       this.setState({data: _data})
     }
@@ -303,6 +325,7 @@
       this.setState({
         data: {$$BID: BID || '', $$BData: BData, $$empty: true},
       })
+      this.loaded = true
       return
     }
 
@@ -321,6 +344,11 @@
     if (result.status) {
       let _data = {}
 
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       if (!result.data || !result.data[0]) {
         _data.$$empty = true
       } else {
diff --git a/src/tabviews/custom/components/card/balcony/index.scss b/src/tabviews/custom/components/card/balcony/index.scss
index e49a9ee..11921aa 100644
--- a/src/tabviews/custom/components/card/balcony/index.scss
+++ b/src/tabviews/custom/components/card/balcony/index.scss
@@ -46,9 +46,9 @@
 
   .loading-mask {
     position: absolute;
-    left: 40px;
+    left: 0px;
     top: 0;
-    right: 40px;
+    right: 0px;
     bottom: 0px;
     display: flex;
     align-items: center;
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index 121091a..7a4dd46 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -46,6 +46,8 @@
     supComs: null
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { data, initdata } = this.props
     let _config = fromJS(this.props.config).toJS()
@@ -102,10 +104,10 @@
     let _data = null
     let _sync = _config.setting.sync === 'true'
 
-    if (_config.setting.sync === 'true' && data) {
+    if (_sync && data) {
       _data = data[_config.dataName] || []
       _sync = false
-    } else if (_config.setting.sync === 'true' && initdata) {
+    } else if (_sync && initdata) {
       _data = initdata || []
       _sync = false
     }
@@ -173,6 +175,8 @@
 
     _config.wrap.wrapClass =  `${_config.wrap.selStyle} ${_config.wrap.cardType || ''} ${_config.wrap.scale}`
 
+    this.loaded = _data !== null
+
     this.setState({
       supComs,
       selected,
@@ -214,6 +218,27 @@
         })
       })
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+        let _data = res.map((item, index) => {
+          item.key = index
+          item.$$uuid = item[config.setting.primaryKey] || ''
+          item.$Index = index + 1 + ''
+
+          if (config.wrap.controlField) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+              item.$disabled = true
+            }
+          }
+
+          return item
+        })
+
+        this.setState({data: _data})
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -252,6 +277,8 @@
           }
         }
       }
+
+      this.loaded = true
 
       this.setState({sync: false, data: _data})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
@@ -526,6 +553,8 @@
     const { config, arr_field, pageIndex, search, BID, BData, selected } = this.state
 
     if (config.setting.supModule && !BID && config.wrap.supKey !== 'false') { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
+      this.loaded = true
+
       this.setState({
         activeKey: '',
         selectKeys: [],
@@ -583,6 +612,11 @@
         start = config.setting.pageSize * (pageIndex - 1) + 1
       }
 
+      this.loaded = true
+      if (config.$cache && pageIndex === 1) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       if (selected !== 'false' || (id && config.wrap.selected !== 'false')) {
         setTimeout(() => {
           this.checkTopLine(id)
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index c6203d6..2ad4a02 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -31,6 +31,8 @@
     selected: 'false',
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { data, initdata } = this.props
     let _config = fromJS(this.props.config).toJS()
@@ -60,16 +62,21 @@
           _data = _data[0] || {$$empty: true}
         }
         _sync = false
+        this.loaded = true
       } else if (_sync && initdata) {
         _data = initdata
         if (Array.isArray(_data)) {
           _data = _data[0] || {$$empty: true}
         }
         _sync = false
+        this.loaded = true
       }
     } else if (_config.wrap.datatype === 'public' && window.GLOB.CacheData.get(_config.wrap.publicId)) {
       _data = window.GLOB.CacheData.get(_config.wrap.publicId)
       _data = fromJS(_data).toJS()
+      this.loaded = true
+    } else if (_config.wrap.datatype === 'static') {
+      this.loaded = true
     }
 
     _data.$$BID = BID || ''
@@ -172,6 +179,17 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {this.loadData(true)})
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        let _data = res[0]
+        _data.$$uuid = _data[config.setting.primaryKey] || ''
+
+        this.setState({data: _data})
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -210,6 +228,8 @@
       _data.$$BData = BData || ''
       _data.$$uuid = _data[config.setting.primaryKey] || ''
 
+      this.loaded = true
+
       this.setState({sync: false, data: _data}, () => {
         if (selected !== 'false') {
           this.checkTopLine()
@@ -234,6 +254,8 @@
       _data.$$BID = BID || ''
       _data.$$BData = BData || ''
       _data.$$uuid = _data[config.setting.primaryKey] || ''
+
+      this.loaded = true
 
       this.setState({data: _data}, () => {
         if (selected !== 'false') {
@@ -360,6 +382,7 @@
       this.setState({
         data: {$$BID: BID || '', $$BData: BData, $$empty: true},
       })
+      this.loaded = true
       return
     }
 
@@ -383,6 +406,11 @@
     if (result.status) {
       let _data = {}
 
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       if (!result.data || !result.data[0]) {
         _data.$$empty = true
       } else {
diff --git a/src/tabviews/custom/components/card/prop-card/index.scss b/src/tabviews/custom/components/card/prop-card/index.scss
index 7b10775..f930a0b 100644
--- a/src/tabviews/custom/components/card/prop-card/index.scss
+++ b/src/tabviews/custom/components/card/prop-card/index.scss
@@ -63,9 +63,9 @@
 
   .loading-mask {
     position: absolute;
-    left: 40px;
+    left: 0px;
     top: 0;
-    right: 40px;
+    right: 0px;
     bottom: 0px;
     display: flex;
     align-items: center;
diff --git a/src/tabviews/custom/components/card/table-card/index.jsx b/src/tabviews/custom/components/card/table-card/index.jsx
index 50e2162..5629e18 100644
--- a/src/tabviews/custom/components/card/table-card/index.jsx
+++ b/src/tabviews/custom/components/card/table-card/index.jsx
@@ -34,6 +34,8 @@
     BData: ''
   }
 
+  loaded = false
+
   /**
    * @description 鍒濆鍖栧鐞�
    * 1銆� initdata 涓烘墦鍗版椂浣跨敤鐨勬暟鎹泦
@@ -104,6 +106,8 @@
 
     _config.wrap.pagestyle = _config.wrap.pagestyle || 'page'
 
+    this.loaded = _data !== null
+
     this.setState({
       sync: _sync,
       BID: BID || '',
@@ -137,6 +141,21 @@
         }, () => {
           this.loadData('timer')
         })
+      })
+    }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        let _data = res.map((item, index) => {
+          item.key = index
+          item.$$uuid = item[config.setting.primaryKey] || ''
+          item.$Index = index + 1 + ''
+          return item
+        })
+
+        this.setState({data: _data})
       })
     }
   }
@@ -177,6 +196,8 @@
         item.$Index = index + 1 + ''
         return item
       })
+
+      this.loaded = true
 
       this.setState({sync: false, data: _data})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
@@ -263,6 +284,8 @@
         data: [],
         total: 0
       })
+
+      this.loaded = true
       return
     }
 
@@ -297,6 +320,11 @@
         start = config.setting.pageSize * (pageIndex - 1) + 1
       }
 
+      this.loaded = true
+      if (config.$cache && pageIndex === 1) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       let data = []
 
       if (type === 'plus') {
diff --git a/src/tabviews/custom/components/card/table-card/index.scss b/src/tabviews/custom/components/card/table-card/index.scss
index 0ef56cb..c44fdec 100644
--- a/src/tabviews/custom/components/card/table-card/index.scss
+++ b/src/tabviews/custom/components/card/table-card/index.scss
@@ -68,9 +68,9 @@
 
   .loading-mask {
     position: absolute;
-    left: 40px;
+    left: 0px;
     top: 0;
-    right: 40px;
+    right: 0px;
     bottom: 0px;
     display: flex;
     align-items: center;
diff --git a/src/tabviews/custom/components/carousel/data-card/index.jsx b/src/tabviews/custom/components/carousel/data-card/index.jsx
index 8829c61..90e9116 100644
--- a/src/tabviews/custom/components/carousel/data-card/index.jsx
+++ b/src/tabviews/custom/components/carousel/data-card/index.jsx
@@ -32,6 +32,8 @@
     visible: false
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { data, initdata } = this.props
     let _config = fromJS(this.props.config).toJS()
@@ -62,6 +64,7 @@
     }
 
     if (_data) {
+      this.loaded = true
       _data = _data.map((item, index) => {
         item.key = index
         item.$$uuid = item[_config.setting.primaryKey] || ''
@@ -129,6 +132,21 @@
         this.loadData('timer')
       })
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        let _data = res.map((item, index) => {
+          item.key = index
+          item.$$uuid = item[config.setting.primaryKey] || ''
+          item.$Index = index + 1 + ''
+          return item
+        })
+
+        this.setState({data: _data})
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -152,6 +170,8 @@
         item.$Index = index + 1
         return item
       })
+
+      this.loaded = true
 
       this.setState({sync: false, data: _data}, () => {
         this.openModal()
@@ -256,6 +276,8 @@
         data: [],
         loading: false
       })
+
+      this.loaded = true
       return
     }
 
@@ -276,6 +298,11 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       this.setState({
         data: result.data.map((item, index) => {
           item.key = index
diff --git a/src/tabviews/custom/components/carousel/prop-card/index.jsx b/src/tabviews/custom/components/carousel/prop-card/index.jsx
index 9b7b8d8..0b5782b 100644
--- a/src/tabviews/custom/components/carousel/prop-card/index.jsx
+++ b/src/tabviews/custom/components/carousel/prop-card/index.jsx
@@ -31,6 +31,8 @@
     visible: false
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { data, initdata } = this.props
     let _config = fromJS(this.props.config).toJS()
@@ -51,7 +53,7 @@
       BID = BData.$BID || ''
     }
     
-    if (_config.setting && _config.wrap.datatype === 'dynamic') {
+    if (_config.wrap.datatype === 'dynamic') {
       _sync = _config.setting.sync === 'true'
 
       if (_sync && data) {
@@ -60,13 +62,17 @@
           _data = _data[0] || {$$empty: true}
         }
         _sync = false
+        this.loaded = true
       } else if (_sync && initdata) {
         _data = initdata
         if (Array.isArray(_data)) {
           _data = _data[0] || {$$empty: true}
         }
         _sync = false
+        this.loaded = true
       }
+    } else if (_config.wrap.datatype === 'static') {
+      this.loaded = true
     }
 
     _data.$$uuid = _data[_config.setting.primaryKey] || ''
@@ -130,6 +136,17 @@
         this.loadData('timer')
       })
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        let _data = res[0]
+        _data.$$uuid = _data[config.setting.primaryKey] || ''
+
+        this.setState({data: _data})
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -166,6 +183,8 @@
       _data.$$uuid = _data[config.setting.primaryKey] || ''
       _data.$$BID = BID || ''
       _data.$$BData = BData || ''
+
+      this.loaded = true
 
       this.setState({sync: false, data: _data}, () => {
         if (config.wrap.display === 'modal') {
@@ -271,6 +290,8 @@
       this.setState({
         data: {$$BID: BID || '', $$BData: BData, $$empty: true}
       })
+
+      this.loaded = true
       return
     }
 
@@ -294,6 +315,11 @@
     if (result.status) {
       let _data = {}
 
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       if (!result.data || !result.data[0]) {
         _data.$$empty = true
       } else {
diff --git a/src/tabviews/custom/components/carousel/prop-card/index.scss b/src/tabviews/custom/components/carousel/prop-card/index.scss
index 6c5d3ee..9236863 100644
--- a/src/tabviews/custom/components/carousel/prop-card/index.scss
+++ b/src/tabviews/custom/components/carousel/prop-card/index.scss
@@ -21,9 +21,9 @@
 
   .loading-mask {
     position: absolute;
-    left: 40px;
+    left: 0px;
     top: 0;
-    right: 40px;
+    right: 0px;
     bottom: 0px;
     display: flex;
     align-items: center;
diff --git a/src/tabviews/custom/components/chart/antv-G6/index.jsx b/src/tabviews/custom/components/chart/antv-G6/index.jsx
index 8eac201..e856a3d 100644
--- a/src/tabviews/custom/components/chart/antv-G6/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-G6/index.jsx
@@ -804,7 +804,6 @@
 
   state = {
     config: null,
-    data: null,
     BID: '',
     BData: '',
     plot: null,
@@ -814,11 +813,12 @@
     empty: true
   }
 
+  data = []
+
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
 
-    let _data = null
     let _sync = _config.setting.sync === 'true'
 
     let BID = ''
@@ -834,10 +834,10 @@
     }
 
     if (_sync && data) {
-      _data = data[config.dataName] || []
+      this.data = data[config.dataName] || []
       _sync = false
     } else if (_sync && initdata) {
-      _data = initdata || []
+      this.data = initdata || []
       _sync = false
     }
 
@@ -850,7 +850,6 @@
 
     this.setState({
       config: _config,
-      data: _data,
       BID: BID || '',
       BData: BData || '',
       arr_field: _config.columns.map(col => col.field).join(','),
@@ -861,44 +860,13 @@
         setTimeout(() => {
           this.loadData()
         }, _config.setting.delay || 0)
-      } else if (config.setting.sync === 'true' && _data) {
-        this.handleData()
       }
     })
-  }
 
-  /**
-   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
-   */
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    const { sync, config } = this.state
-
-    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
-      let _data = []
-
-      if (nextProps.data && nextProps.data[config.dataName]) {
-        _data = nextProps.data[config.dataName]
-      }
-
-      this.setState({sync: false, data: _data}, () => {
-        this.handleData()
-      })
-    } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
-      this.setState({}, () => {
-        this.loadData()
-      })
+    if (this.data.length > 0) {
+      this.handleData()
     }
-  }
-
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.state), fromJS(nextState))
-  }
-
-  componentDidMount () {
-    const { config } = this.state
-    MKEmitter.addListener('reloadData', this.reloadData)
-    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
-
+    
     let that = this
 
     if (config.plot.subtype === 'mindmap') {
@@ -1028,6 +996,53 @@
   }
 
   /**
+   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
+   */
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { sync, config } = this.state
+
+    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
+      let _data = []
+
+      if (nextProps.data && nextProps.data[config.dataName]) {
+        _data = nextProps.data[config.dataName]
+      }
+
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
+        this.handleData()
+      }
+
+      this.setState({sync: false})
+    } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      this.setState({}, () => {
+        this.loadData()
+      })
+    }
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  componentDidMount () {
+    const { config, sync } = this.state
+    MKEmitter.addListener('reloadData', this.reloadData)
+    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
+
+    if (config.$cache && (config.setting.sync !== 'true' || sync)) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.data.length > 0) return
+
+        if (!is(fromJS(this.data), fromJS(res))) {
+          this.data = res
+          this.handleData()
+        }
+      })
+    }
+  }
+
+  /**
    * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
    */
   componentWillUnmount () {
@@ -1062,11 +1077,10 @@
     const { config, arr_field, BID } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
-      this.setState({
-        data: {}
-      }, () => {
+      if (!is(fromJS(this.data), fromJS([]))) {
+        this.data = []
         this.handleData()
-      })
+      }
       return
     }
 
@@ -1086,14 +1100,18 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let data = result.data || []
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
 
       this.setState({
-        data,
         loading: false
-      }, () => {
-        this.handleData()
       })
+
+      if (!is(fromJS(this.data), fromJS(result.data || []))) {
+        this.data = result.data || []
+        this.handleData()
+      }
     } else {
       this.setState({
         loading: false
@@ -1114,7 +1132,7 @@
   }
 
   getdata = () => {
-    const { plot, data, config, BData } = this.state
+    const { plot, config, BData } = this.state
     
     let root = {
       label: 'Root',
@@ -1140,7 +1158,7 @@
     let _options = []
     let logMap = new Map()
 
-    data.forEach(item => {
+    this.data.forEach(item => {
       let pval = item[plot.parentField]
       let val = item[plot.valueField]
       let label = item[plot.labelField] || ''
@@ -1256,14 +1274,20 @@
   }
 
   handleData = () => {
-    const { plot, data } = this.state
-
     let _element = document.getElementById(this.state.chartId)
     if (_element) {
       _element.innerHTML = ''
     }
 
-    if (!data || data.length === 0) {
+    setTimeout(() => {
+      this.viewrender()
+    }, 100)
+  }
+
+  viewrender = () => {
+    const { plot } = this.state
+
+    if (this.data.length === 0) {
       this.setState({empty: true})
     } else {
       this.setState({empty: false})
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
index ee845a8..5bc343a 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -37,17 +37,17 @@
     transfield: {},            // 瀛楁鍚嶇О缈昏瘧
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     plot: null,                // 鍥捐〃璁剧疆
-    data: null,                // 鏁版嵁
     search: null,              // 鎼滅储鏉′欢
     vFields: [],               // 鏁板�煎瓧娈�
     vstFields: null,           // 缁熻鏁版嵁鍊煎瓧娈典俊鎭�
     chart: null
   }
 
+  data = []
+
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
-    let _data = null
     let _sync = config.setting.sync === 'true'
 
     let BID = ''
@@ -62,11 +62,11 @@
       BID = BData.$BID || ''
     }
 
-    if (config.setting.sync === 'true' && data) {
-      _data = data[config.dataName] || []
+    if (_sync && data) {
+      this.data = data[config.dataName] || []
       _sync = false
-    } else if (config.setting.sync === 'true' && initdata) {
-      _data = initdata || []
+    } else if (_sync && initdata) {
+      this.data = initdata || []
       _sync = false
     }
 
@@ -335,7 +335,6 @@
 
     this.setState({
       config: _config,
-      data: _data,
       BID: BID || '',
       vFields: vFields,
       vstFields: vstFields,
@@ -349,10 +348,12 @@
         setTimeout(() => {
           this.loadData()
         }, _config.setting.delay || 0)
-      } else if (config.setting.sync === 'true' && _data) {
-        this.handleData()
       }
     })
+
+    if (this.data.length > 0) {
+      this.handleData()
+    }
   }
 
   /**
@@ -367,9 +368,12 @@
         _data = nextProps.data[config.dataName] || []
       }
 
-      this.setState({sync: false, data: _data}, () => {
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
         this.handleData()
-      })
+      }
+
+      this.setState({sync: false})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
         this.loadData()
@@ -382,7 +386,7 @@
   }
 
   componentDidMount () {
-    const { config } = this.state
+    const { config, sync } = this.state
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -393,6 +397,17 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {
         this.loadData(true)
+      })
+    }
+
+    if (config.$cache && (config.setting.sync !== 'true' || sync)) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.data.length > 0) return
+
+        if (!is(fromJS(this.data), fromJS(res))) {
+          this.data = res
+          this.handleData()
+        }
       })
     }
   }
@@ -488,11 +503,10 @@
     const { config, arr_field, BID, search } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
-      this.setState({
-        data: []
-      }, () => {
+      if (!is(fromJS(this.data), fromJS([]))) {
+        this.data = []
         this.handleData()
-      })
+      }
       return
     }
 
@@ -522,19 +536,18 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let reset = true
-
-      if (hastimer && is(fromJS(result.data), fromJS(this.state.data))) {
-        reset = false
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
       }
 
       this.setState({
-        data: result.data,
         loading: false
-      }, () => {
-        if (!reset) return
-        this.handleData()
       })
+
+      if (!is(fromJS(this.data), fromJS(result.data || []))) {
+        this.data = result.data || []
+        this.handleData()
+      }
     } else {
       this.setState({
         loading: false
@@ -575,15 +588,15 @@
    * 3銆佹煴鐘跺浘鏁版嵁琛ラ綈
    */
   getdata = () => {
-    const { data, plot, vFields, config } = this.state
+    const { plot, vFields, config } = this.state
 
-    if (!data || data.length === 0) {
+    if (this.data.length === 0) {
       this.setState({empty: true})
       return []
     }
 
     let _data = []
-    let _cdata = fromJS(data).toJS()
+    let _cdata = fromJS(this.data).toJS()
 
     if (plot.repeat === 'average') {
       let _mdata = new Map()
@@ -717,7 +730,7 @@
    * @description 缁熻鏁版嵁棰勫鐞�
    */
   getStaticMsg = () => {
-    const { plot, vstFields, data } = this.state
+    const { plot, vstFields } = this.state
 
     let percent = false
     let decimal = vstFields ? vstFields.decimal : 0
@@ -726,13 +739,13 @@
       percent = true
     }
 
-    if (!data || data.length === 0) {
+    if (this.data.length === 0) {
       this.setState({empty: true})
       return []
     }
 
     let _data = []
-    let _cdata = fromJS(data).toJS()
+    let _cdata = fromJS(this.data).toJS()
 
     if (plot.repeat === 'average') {
       let _mdata = new Map()
diff --git a/src/tabviews/custom/components/chart/antv-dashboard/index.jsx b/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
index 7252311..c505abf 100644
--- a/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
@@ -65,15 +65,15 @@
     chartId: Utils.getuuid(),  // 鍥捐〃Id
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     plot: null,                // 鍥捐〃璁剧疆
-    data: {},                  // 鏁版嵁
     chart: null
   }
+
+  data = {}
 
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
 
-    let _data = null
     let _sync = _config.setting.sync === 'true'
 
     let BID = ''
@@ -89,21 +89,18 @@
     }
 
     if (_sync && data) {
-      _data = data[config.dataName] || []
+      this.data = data[config.dataName] || []
       _sync = false
     } else if (_sync && initdata) {
-      _data = initdata || []
+      this.data = initdata || []
       _sync = false
     }
 
-    if (_config.subtype === 'ratioboard') {
-      _data = _data || []
-    } else {
-      if (_data && Array.isArray(_data)) {
-        _data = _data[0] || {}
-      } else {
-        _data = {}
+    if (_config.subtype !== 'ratioboard') {
+      if (Array.isArray(this.data)) {
+        this.data = this.data[0] || {}
       }
+      this.data.value = this.data[config.plot.valueField] || 0
     }
 
     _config.plot.height = Utils.getHeight(_config.plot.height)
@@ -116,7 +113,6 @@
 
     this.setState({
       config: _config,
-      data: _data,
       BID: BID || '',
       arr_field: _config.columns.map(col => col.field).join(','),
       plot: _config.plot,
@@ -126,10 +122,12 @@
         setTimeout(() => {
           this.loadData()
         }, _config.setting.delay || 0)
-      } else if (config.setting.sync === 'true') {
-        this.handleData()
       }
     })
+
+    if (config.setting.sync === 'true' && !_sync) {
+      this.handleData()
+    }
   }
 
   /**
@@ -141,24 +139,22 @@
     if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
       let _data = null
 
-      if (config.subtype === 'ratioboard') {
-        _data = []
-        if (nextProps.data && nextProps.data[config.dataName]) {
-          _data = nextProps.data[config.dataName] || []
-        }
-      } else {
-        _data = {}
-        if (nextProps.data && nextProps.data[config.dataName]) {
-          _data = nextProps.data[config.dataName] || {}
-        }
-        if (_data.hasOwnProperty(config.plot.valueField)) {
-          _data.value = _data[config.plot.valueField]
+      if (nextProps.data && nextProps.data[config.dataName]) {
+        _data = nextProps.data[config.dataName]
+        if (config.subtype !== 'ratioboard') {
+          if (Array.isArray(_data)) {
+            _data = _data[0] || {}
+          }
+          _data.value = _data[config.plot.valueField] || 0
         }
       }
 
-      this.setState({sync: false, data: _data}, () => {
+      if (_data && !is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
         this.handleData()
-      })
+      }
+
+      this.setState({sync: false})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
         this.loadData()
@@ -171,7 +167,7 @@
   }
 
   componentDidMount () {
-    const { config } = this.state
+    const { config, sync } = this.state
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -180,6 +176,25 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {
         this.loadData(true)
+      })
+    }
+
+    if (config.$cache && (config.setting.sync !== 'true' || sync)) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res) return
+
+        let _data = null
+        if (config.subtype === 'ratioboard') {
+          _data = res
+        } else {
+          _data = res[0]
+          _data.value = _data[config.plot.valueField] || 0
+        }
+
+        if (!is(fromJS(this.data), fromJS(_data))) {
+          this.data = _data
+          this.handleData()
+        }
       })
     }
   }
@@ -221,7 +236,10 @@
     if (_element) {
       _element.innerHTML = ''
     }
-    this.viewrender()
+    
+    setTimeout(() => {
+      this.viewrender()
+    }, 100)
   }
 
   async loadData (hastimer) {
@@ -229,11 +247,17 @@
     const { config, arr_field, BID } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
-      this.setState({
-        data: {}
-      }, () => {
+      let _data = null
+      if (config.subtype === 'ratioboard') {
+        _data = []
+      } else {
+        _data = {value: 0}
+      }
+
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
         this.handleData()
-      })
+      }
       return
     }
 
@@ -255,27 +279,25 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let data = null
-      if (config.subtype === 'ratioboard') {
-        data = result.data || []
-      } else {
-        data = {}
-        if (result.data && result.data[0] && result.data[0].hasOwnProperty(config.plot.valueField)) {
-          data.value = result.data[0][config.plot.valueField]
-        }
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
       }
-      let reset = true
 
-      if (hastimer && is(fromJS(data), fromJS(this.state.data))) {
-        reset = false
+      let _data = null
+      if (config.subtype === 'ratioboard') {
+        _data = result.data || []
+      } else {
+        _data = result.data && result.data[0] ? result.data && result.data[0] : {}
+        _data.value = _data.value[config.plot.valueField] || 0
+      }
+
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
+        this.handleData()
       }
 
       this.setState({
-        data,
         loading: false
-      }, () => {
-        if (!reset) return
-        this.handleData()
       })
     } else {
       this.setState({
@@ -307,7 +329,7 @@
   }
 
   getratiodata = () => {
-    const { data, plot } = this.state
+    const { plot } = this.state
 
     let colors = {}
     if (plot.colors && plot.colors.length > 0) {
@@ -316,7 +338,7 @@
       })
     }
 
-    return data.map(item => {
+    return this.data.map(item => {
       let val = +item[plot.valueField]
       let type = item[plot.labelField] || ''
       if (isNaN(val)) {
@@ -426,22 +448,15 @@
    * @description 浠〃鐩樻覆鏌�
    */
   dashboardrender = () => {
-    const { plot, chartId, data } = this.state
+    const { plot, chartId } = this.state
 
-    let _data = fromJS(data).toJS()
+    let _data = fromJS(this.data).toJS()
+    _data.value = +_data.value
 
-    if (_data.hasOwnProperty('value')) {
-      if (_data.value === '' || _data.value === null) {
-        delete _data.value
-      } else {
-        _data.value = +_data.value
-
-        if (isNaN(_data.value)) {
-          delete _data.value
-        } else if (_data.value > plot.maxValue) {
-          _data.value = plot.maxValue
-        }
-      }
+    if (isNaN(_data.value)) {
+      _data.value = 0
+    } else if (_data.value > plot.maxValue) {
+      _data.value = plot.maxValue
     }
 
     const chart = new Chart({
@@ -559,8 +574,9 @@
       })
     }
 
-    if (data.hasOwnProperty('value')) {
-      let val = data.value
+    let val = +this.data.value
+
+    if (!isNaN(val)) {
       if (plot.percent !== 'false' && plot.maxValue) {
         val = +(val / plot.maxValue * 100).toFixed(2) + ' %'
       }
diff --git a/src/tabviews/custom/components/chart/antv-pie/index.jsx b/src/tabviews/custom/components/chart/antv-pie/index.jsx
index f6893b8..216be2f 100644
--- a/src/tabviews/custom/components/chart/antv-pie/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -32,16 +32,16 @@
     title: '',                 // 缁勪欢鏍囬
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     plot: null,                // 鍥捐〃璁剧疆
-    data: null,                // 鏁版嵁
     search: null,              // 鎼滅储鏉′欢
     chart: null
   }
+
+  data = []
 
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
 
-    let _data = null
     let _sync = config.setting.sync === 'true'
 
     let BID = ''
@@ -56,11 +56,11 @@
       BID = BData.$BID || ''
     }
 
-    if (config.setting.sync === 'true' && data) {
-      _data = data[config.dataName] || []
+    if (_sync && data) {
+      this.data = data[config.dataName] || []
       _sync = false
-    } else if (config.setting.sync === 'true' && initdata) {
-      _data = initdata || []
+    } else if (_sync && initdata) {
+      this.data = initdata || []
       _sync = false
     }
 
@@ -83,7 +83,6 @@
 
     this.setState({
       config: _config,
-      data: _data,
       BID: BID || '',
       arr_field: _config.columns.map(col => col.field).join(','),
       plot: _config.plot,
@@ -95,10 +94,12 @@
         setTimeout(() => {
           this.loadData()
         }, _config.setting.delay || 0)
-      } else if (config.setting.sync === 'true' && _data) {
-        this.handleData()
       }
     })
+
+    if (this.data.length > 0) {
+      this.handleData()
+    }
   }
 
   /**
@@ -113,9 +114,12 @@
         _data = nextProps.data[config.dataName] || []
       }
 
-      this.setState({sync: false, data: _data}, () => {
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
         this.handleData()
-      })
+      }
+
+      this.setState({sync: false})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
         this.loadData()
@@ -128,7 +132,7 @@
   }
 
   componentDidMount () {
-    const { config } = this.state
+    const { config, sync } = this.state
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -137,6 +141,17 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {
         this.loadData(true)
+      })
+    }
+
+    if (config.$cache && (config.setting.sync !== 'true' || sync)) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.data.length > 0) return
+
+        if (!is(fromJS(this.data), fromJS(res))) {
+          this.data = res
+          this.handleData()
+        }
       })
     }
   }
@@ -174,12 +189,18 @@
   }
 
   handleData = () => {
-    const { plot, chartId } = this.state
-    
-    let _element = document.getElementById(chartId)
+    let _element = document.getElementById(this.state.chartId)
     if (_element) {
       _element.innerHTML = ''
     }
+
+    setTimeout(() => {
+      this.viewrender()
+    }, 100)
+  }
+
+  viewrender = () => {
+    const { plot } = this.state
 
     if (plot.shape === 'nest') {
       this.nestrender()
@@ -193,11 +214,10 @@
     const { config, arr_field, search, BID } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
-      this.setState({
-        data: []
-      }, () => {
+      if (!is(fromJS(this.data), fromJS([]))) {
+        this.data = []
         this.handleData()
-      })
+      }
       return
     }
 
@@ -227,19 +247,18 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let reset = true
-
-      if (hastimer && is(fromJS(result.data), fromJS(this.state.data))) {
-        reset = false
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
       }
 
       this.setState({
-        data: result.data,
         loading: false
-      }, () => {
-        if (!reset) return
-        this.handleData()
       })
+
+      if (!is(fromJS(this.data), fromJS(result.data || []))) {
+        this.data = result.data || []
+        this.handleData()
+      }
     } else {
       this.setState({
         loading: false
@@ -267,15 +286,15 @@
    * 3銆佹煴鐘跺浘鏁版嵁琛ラ綈
    */
   getdata = () => {
-    const { data, plot } = this.state
+    const { plot } = this.state
 
-    if (!data) {
+    if (this.data.length === 0) {
       this.setState({empty: true})
       return []
     }
 
     let _data = []
-    let _cdata = fromJS(data).toJS()
+    let _cdata = fromJS(this.data).toJS()
 
     if (plot.repeat === 'average') {
       let _mdata = new Map()
@@ -360,15 +379,15 @@
   }
 
   getnestdata = () => {
-    const { data, plot } = this.state
+    const { plot } = this.state
 
-    if (!data) {
+    if (this.data.length === 0) {
       this.setState({empty: true})
       return []
     }
 
     let _data = []
-    let _cdata = fromJS(data).toJS()
+    let _cdata = fromJS(this.data).toJS()
 
     if (plot.repeat === 'average') {
       let _mdata = new Map()
diff --git a/src/tabviews/custom/components/chart/antv-scatter/index.jsx b/src/tabviews/custom/components/chart/antv-scatter/index.jsx
index 644a98f..a36ef44 100644
--- a/src/tabviews/custom/components/chart/antv-scatter/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-scatter/index.jsx
@@ -33,15 +33,15 @@
     chartId: Utils.getuuid(),  // 鍥捐〃Id
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     plot: null,                // 鍥捐〃璁剧疆
-    data: null,                // 鏁版嵁
     search: null,              // 鎼滅储鏉′欢
     chart: null
   }
 
+  data = []
+
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
-    let _data = null
     let _sync = config.setting.sync === 'true'
 
     let BID = ''
@@ -56,11 +56,11 @@
       BID = BData.$BID || ''
     }
 
-    if (config.setting.sync === 'true' && data) {
-      _data = data[config.dataName] || []
+    if (_sync && data) {
+      this.data = data[config.dataName] || []
       _sync = false
-    } else if (config.setting.sync === 'true' && initdata) {
-      _data = initdata || []
+    } else if (_sync && initdata) {
+      this.data = initdata || []
       _sync = false
     }
 
@@ -74,9 +74,8 @@
 
     this.setState({
       config: _config,
-      data: _data,
       BID: BID || '',
-      empty: !_data,
+      empty: this.data.length === 0,
       arr_field: _config.columns.map(col => col.field).join(','),
       plot: _config.plot,
       sync: _sync,
@@ -86,10 +85,12 @@
         setTimeout(() => {
           this.loadData()
         }, _config.setting.delay || 0)
-      } else if (config.setting.sync === 'true' && _data) {
-        this.handleData()
       }
     })
+
+    if (this.data.length > 0) {
+      this.handleData()
+    }
   }
 
   /**
@@ -104,9 +105,12 @@
         _data = nextProps.data[config.dataName] || []
       }
 
-      this.setState({sync: false, data: _data, empty: !_data,}, () => {
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
         this.handleData()
-      })
+      }
+
+      this.setState({sync: false, empty: _data.length === 0})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
         this.loadData()
@@ -119,7 +123,7 @@
   }
 
   componentDidMount () {
-    const { config } = this.state
+    const { config, sync } = this.state
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -130,6 +134,19 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {
         this.loadData(true)
+      })
+    }
+
+    if (config.$cache && (config.setting.sync !== 'true' || sync)) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.data.length > 0) return
+
+        if (!is(fromJS(this.data), fromJS(res))) {
+          this.data = res
+          this.handleData()
+        }
+
+        this.setState({empty: false})
       })
     }
   }
@@ -225,12 +242,12 @@
     const { config, arr_field, BID, search } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
-      this.setState({
-        data: [],
-        empty: false,
-      }, () => {
+      this.setState({ empty: true })
+
+      if (!is(fromJS(this.data), fromJS([]))) {
+        this.data = []
         this.handleData()
-      })
+      }
       return
     }
 
@@ -260,20 +277,19 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let reset = true
-
-      if (hastimer && is(fromJS(result.data), fromJS(this.state.data))) {
-        reset = false
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
       }
       
       this.setState({
-        data: result.data,
-        empty: false,
+        empty: !result.data || result.data.length === 0,
         loading: false
-      }, () => {
-        if (!reset) return
-        this.handleData()
       })
+
+      if (!is(fromJS(this.data), fromJS(result.data || []))) {
+        this.data = result.data || []
+        this.handleData()
+      }
     } else {
       this.setState({
         loading: false
@@ -302,21 +318,24 @@
     if (_element) {
       _element.innerHTML = ''
     }
-    this.scatterrender()
+
+    setTimeout(() => {
+      this.scatterrender()
+    }, 100)
   }
 
   /**
    * @description 鏁g偣鍥炬覆鏌�
    */
   scatterrender = () => {
-    const { plot, data, chartId } = this.state
+    const { plot, chartId } = this.state
     const chart = new Chart({
       container: chartId,
       autoFit: true,
       height: plot.height
     })
 
-    chart.data(data);
+    chart.data(this.data);
     chart.scale({
       [plot.Xaxis]: { nice: true },
       [plot.Yaxis]: { nice: true },
diff --git a/src/tabviews/custom/components/chart/custom-chart/index.jsx b/src/tabviews/custom/components/chart/custom-chart/index.jsx
index a3f4b6d..19713cf 100644
--- a/src/tabviews/custom/components/chart/custom-chart/index.jsx
+++ b/src/tabviews/custom/components/chart/custom-chart/index.jsx
@@ -28,14 +28,14 @@
     loading: false,            // 鏁版嵁鍔犺浇鐘舵��
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     plot: null,                // 鍥捐〃璁剧疆
-    data: null,                // 鏁版嵁
     search: null,              // 鎼滅储鏉′欢
   }
+
+  data = []
 
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
-    let _data = null
     let _sync = config.setting.sync === 'true'
 
     let BID = ''
@@ -50,11 +50,11 @@
       BID = BData.$BID || ''
     }
 
-    if (config.setting.sync === 'true' && data) {
-      _data = data[config.dataName] || []
+    if (_sync && data) {
+      this.data = data[config.dataName] || []
       _sync = false
-    } else if (config.setting.sync === 'true' && initdata) {
-      _data = initdata || []
+    } else if (_sync && initdata) {
+      this.data = initdata || []
       _sync = false
     }
 
@@ -63,8 +63,7 @@
 
     this.setState({
       config: _config,
-      data: _data,
-      empty: !_data || _data.length === 0,
+      empty: this.data.length === 0,
       BID: BID || '',
       arr_field: _config.columns.map(col => col.field).join(','),
       plot: _config.plot,
@@ -75,10 +74,12 @@
         setTimeout(() => {
           this.loadData()
         }, _config.setting.delay || 0)
-      } else if (config.setting.sync === 'true' && _data) {
-        this.handleData()
       }
     })
+
+    if (this.data.length > 0) {
+      this.handleData()
+    }
   }
 
   /**
@@ -93,9 +94,12 @@
         _data = nextProps.data[config.dataName] || []
       }
 
-      this.setState({sync: false, data: _data, empty: _data.length === 0}, () => {
+      if (!is(fromJS(this.data), fromJS(_data))) {
+        this.data = _data
         this.handleData()
-      })
+      }
+
+      this.setState({sync: false, empty: _data.length === 0})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
         this.loadData()
@@ -108,7 +112,7 @@
   }
 
   componentDidMount () {
-    const { config } = this.state
+    const { config, sync } = this.state
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -119,6 +123,18 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {
         this.loadData(true)
+      })
+    }
+
+    if (config.$cache && (config.setting.sync !== 'true' || sync)) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.data.length > 0) return
+
+        if (!is(fromJS(this.data), fromJS(res))) {
+          this.data = res
+          this.handleData()
+        }
+        this.setState({empty: false})
       })
     }
   }
@@ -215,10 +231,13 @@
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
       this.setState({
-        data: []
-      }, () => {
-        this.handleData()
+        empty: true
       })
+
+      if (!is(fromJS(this.data), fromJS([]))) {
+        this.data = []
+        this.handleData()
+      }
       return
     }
 
@@ -248,20 +267,19 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let reset = true
-
-      if (hastimer && is(fromJS(result.data), fromJS(this.state.data))) {
-        reset = false
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
       }
 
       this.setState({
-        data: result.data,
         loading: false,
-        empty: result.data.length === 0
-      }, () => {
-        if (!reset) return
-        this.handleData()
+        empty: !result.data || result.data.length === 0
       })
+
+      if (!is(fromJS(this.data), fromJS(result.data || []))) {
+        this.data = result.data || []
+        this.handleData()
+      }
     } else {
       this.setState({
         loading: false
@@ -287,14 +305,14 @@
     
     setTimeout(() => {
       this.viewrender()
-    }, 150)
+    }, 100)
   }
 
   /**
    * @description 鍥捐〃娓叉煋鍒嗙粍
    */
   viewrender = () => {
-    const { config, data } = this.state
+    const { config } = this.state
 
     if (!config.plot.script) return
 
@@ -302,7 +320,7 @@
       try {
         // eslint-disable-next-line
         let func = new Function('Chart', 'DataSet', 'wrap', 'data', 'config', config.plot.script)
-        func(Chart, DataSet, this.wrap, data, config)
+        func(Chart, DataSet, this.wrap, this.data, config)
       } catch (e) {
         console.warn(e)
   
@@ -316,7 +334,7 @@
       try {
         // eslint-disable-next-line
         let func = new Function('echarts', 'DataSet', 'wrap', 'data', 'config', config.plot.script)
-        func(echarts, DataSet, this.wrap, data, config)
+        func(echarts, DataSet, this.wrap, this.data, config)
       } catch (e) {
         console.warn(e)
   
@@ -347,7 +365,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch}/>
         <div className="canvas-wrap" style={{height: (config.plot.height + 30) + 'px'}}>
           <div className={'canvas' + (empty ? ' empty' : '')} style={{height: config.plot.height + 'px'}} ref={ref => this.wrap = ref}></div>
         </div>
diff --git a/src/tabviews/custom/components/code/sand-box/index.jsx b/src/tabviews/custom/components/code/sand-box/index.jsx
index 2456f8b..a9edce6 100644
--- a/src/tabviews/custom/components/code/sand-box/index.jsx
+++ b/src/tabviews/custom/components/code/sand-box/index.jsx
@@ -24,6 +24,8 @@
     html: '',
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { data, initdata } = this.props
     let _config = fromJS(this.props.config).toJS()
@@ -49,12 +51,15 @@
       if (_sync && data) {
         _data = data[_config.dataName] || {}
         _sync = false
+        this.loaded = true
       } else if (_sync && initdata) {
         _data = initdata || {}
         _sync = false
+        this.loaded = true
       }
     } else {
       _data = {}
+      this.loaded = true
     }
     
     if (_config.css) {
@@ -84,7 +89,19 @@
   }
 
   componentDidMount () {
+    const { config } = this.state
+
     MKEmitter.addListener('reloadData', this.reloadData)
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        this.setState({data: res[0]}, () => {
+          this.renderView()
+        })
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -110,9 +127,15 @@
         _data = nextProps.data[config.dataName]
       }
 
-      this.setState({sync: false, data: _data}, () => {
-        this.renderView()
-      })
+      this.loaded = true
+
+      this.setState({sync: false, data: _data})
+
+      if (!is(fromJS(this.state.data), fromJS(_data))) {
+        setTimeout(() => {
+          this.renderView()
+        }, 10)
+      }
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
         this.loadData()
@@ -143,6 +166,7 @@
         data: {},
         loading: false
       })
+      this.loaded = true
       return
     }
 
@@ -164,12 +188,21 @@
     if (result.status) {
       let _data = result.data || {}
 
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       this.setState({
         data: _data,
         loading: false
-      }, () => {
-        this.renderView()
       })
+      
+      if (!is(fromJS(this.state.data), fromJS(_data))) {
+        setTimeout(() => {
+          this.renderView()
+        }, 10)
+      }
     } else {
       this.setState({
         loading: false
diff --git a/src/tabviews/custom/components/group/normal-group/index.jsx b/src/tabviews/custom/components/group/normal-group/index.jsx
index 3fe7aea..44124b6 100644
--- a/src/tabviews/custom/components/group/normal-group/index.jsx
+++ b/src/tabviews/custom/components/group/normal-group/index.jsx
@@ -103,14 +103,15 @@
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
   loadmaindata = (params) => {
+    const { config } = this.props
     let BID = ''
-    let BData = window.GLOB.CacheData.get(this.props.config.$pageId)
+    let BData = window.GLOB.CacheData.get(config.$pageId)
 
     if (BData) {
       BID = BData.$BID || ''
     }
 
-    let param = getStructuredParams(params, this.props.config, BID)
+    let param = getStructuredParams(params, config, BID)
 
     Api.genericInterface(param).then(result => {
       if (result.status) {
@@ -119,6 +120,16 @@
         delete result.ErrMesg
         delete result.ErrCode
 
+        if (config.$cache) {
+          params.forEach((item) => {
+            let _data = result[item.name] || ''
+            if (_data && !Array.isArray(_data)) {
+              _data = [_data]
+            }
+            Api.writeCacheConfig(item.uuid, _data)
+          })
+        }
+
         this.setState({
           data: result
         })
diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx
index 2eb3f9c..1b18806 100644
--- a/src/tabviews/custom/components/module/voucher/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/index.jsx
@@ -20,10 +20,11 @@
     BID: '',
     config: null,
     loading: false,
-    data: null,
+    data: [],
     disableAdd: false,
     disableSave: false,
     typeOptions: [],
+    subjects: [],
     charType: '',
     charInt: '',
     vouDate: null,
@@ -77,7 +78,14 @@
     const { config } = this.state
 
     if (config.wrap.supBook === MenuID) {
-      this.setState({ book: data }, () => {
+      let month = data.months
+      let vouDate = moment()
+
+      if (month && month < moment().format('YYYY-MM')) {
+        vouDate = moment(month, 'YYYY-MM').endOf('month')
+      }
+
+      this.setState({ book: data, vouDate }, () => {
         this.loadData()
       })
       return
@@ -118,7 +126,26 @@
         typeOptions: typeOptions,
         charType: typeOptions[0] ? typeOptions[0].voucher_class : '',
         charInt: typeOptions[0] ? typeOptions[0].voucher_char_int : '',
+        subjects: res.subjects || [],
       })
+
+      setTimeout(() => {
+        this.getVoucher()
+      }, 200)
+    })
+  }
+
+
+  getVoucher = () => {
+    let data = [
+      {remark: '鎻愮幇', subjectscode: '1001', subjectsname: '搴撳瓨鐜伴噾', debtor: 124, creditor: ''},
+      {remark: '璐叆鍥哄畾璧勪骇', subjectscode: '1001', subjectsname: '搴撳瓨鐜伴噾', debtor: '', creditor: 124},
+      {remark: '杞粨閿�鍞垚鏈�', subjectscode: '1001', subjectsname: '搴撳瓨鐜伴噾', debtor: -524, creditor: ''},
+      {remark: '鎻愮幇', subjectscode: '1001', subjectsname: '搴撳瓨鐜伴噾', debtor: 34, creditor: ''},
+    ]
+
+    this.setState({
+      data: data
     })
   }
 
@@ -134,12 +161,8 @@
 
   }
 
-  changeVoucherDate = () => {
-
-  }
-
   render() {
-    const { config, disableSave, disableAdd, typeOptions, charType, charInt, data } = this.state
+    const { config, disableSave, disableAdd, typeOptions, charType, charInt, data, vouDate, subjects } = this.state
 
     return (
       <div className="menu-voucher-wrap" style={config.style}>
@@ -153,15 +176,15 @@
         {config.wrap.type === 'edit' ? <div className="voucher-body">
           <div className="pre-wrap">
             <div className="voucher-code">
-              <Select value={charType} dropdownClassName="mk-vcode-dropdown" onChange={(val, option) => this.setState({charType: val, charInt: option.props.charInt})}>
+              <Select value={charType} dropdownClassName="mk-vcode-dropdown" onChange={(val, option) => this.setState({charType: val, charInt: option.props.charint})}>
                 {typeOptions.map(option =>
-                  <Select.Option value={option.voucher_class} charInt={option.voucher_char_int}>{option.voucher_char}</Select.Option>
+                  <Select.Option key={option.voucher_char_int} value={option.voucher_class} charint={option.voucher_char_int}>{option.voucher_char}</Select.Option>
                 )}
               </Select>
               <Input value={charInt} autoComplete="off" onChange={(e) => this.setState({charInt: e.target.value})}/> 鍙�
             </div>
             <div className="voucher-date">
-              鏃ユ湡锛�<DatePicker onChange={this.changeVoucherDate}/>
+              鏃ユ湡锛�<DatePicker value={vouDate} onChange={(val) => this.setState({vouDate: val})}/>
             </div>
             <div className="voucher-affix">
               闄勫崟鎹� <Input autoComplete="off" /> 寮�
@@ -169,7 +192,7 @@
               <Button type="link" className="" onClick={this.triggerprint}>澶囨敞</Button>
             </div>
           </div>
-          <VoucherTable config={config} data={data}/>
+          <VoucherTable config={config} subjects={subjects} data={data}/>
         </div> : null}
         {config.wrap.type === 'check' ? <div className="voucher-body">
           <div className="pre-wrap">
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
index 8d5240d..b79fdd7 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Table, Modal, Input, InputNumber, notification, message, AutoComplete } from 'antd'
+import { Table, Modal, Input, InputNumber, notification, message, AutoComplete, Select } from 'antd'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -78,7 +78,7 @@
       if (col.field === 'creditor') {
         MKEmitter.emit('nextLine', col, record)
       } else {
-        let cl = {remark: 'subject', subject: 'debtor', debtor: 'creditor'}
+        let cl = {remark: 'subjectscode', subjectscode: 'debtor', debtor: 'creditor'}
         MKEmitter.emit('tdFocus', cl[col.uuid] + record.uuid)
       }
     }, 50)
@@ -89,10 +89,19 @@
 
     if (record.type === 'total') return
 
-    this.setState({editing: true, value: record[col.field]}, () => {
-      let node = document.getElementById(col.uuid + record.uuid)
-      node && node.select()
-    })
+    if (col.field === 'subjectscode') {
+      this.setState({editing: true}, () => {
+        try {
+          let node = document.getElementById(col.uuid + record.uuid)
+          node.click()
+        } catch(e) {}
+      })
+    } else {
+      this.setState({editing: true, value: record[col.field]}, () => {
+        let node = document.getElementById(col.uuid + record.uuid)
+        node && node.select()
+      })
+    }
   }
 
   onBlur = () => {
@@ -100,6 +109,8 @@
     const { value } = this.state
 
     this.setState({editing: false})
+
+    if (col.field === 'subjectscode') return
 
     if (value !== record[col.field]) {
       let line = {...record, [col.field]: value}
@@ -118,12 +129,28 @@
     this.setState({value: val})
   }
 
-  complete = (key, option) => {
-    this.setState({value: option.props.value})
+  complete = (val) => {
+    this.setState({value: val}, () => {
+      this.onBlur()
+    })
+  }
+
+  onSelectChange = (val, option) => {
+    const { col, record } = this.props
+
+    this.setState({editing: false})
+
+    let line = {...record, ...option.props.extra}
+
+    MKEmitter.emit('changeRecord', col.tableId, line)
+
+    setTimeout(() => {
+      MKEmitter.emit('tdFocus', 'debtor' + record.uuid)
+    }, 50)
   }
 
   render() {
-    let { col, record, className } = this.props
+    let { col, record, subjects, className } = this.props
     const { editing } = this.state
 
     let children = null
@@ -154,15 +181,27 @@
           children = <div className="content-wrap" onClick={this.focus}>{val}</div>
         }
       }
-    } else if (col.field === 'subject') {
+    } else if (col.field === 'subjectscode') {
       if (record.type === 'total') {
         colSpan = 0
       } else {
-        let val = record.subject || ''
-  
         if (editing) {
-          children = <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
+          children = <Select
+            showSearch
+            defaultValue={record.subjectscode || ''}
+            dropdownClassName="edit-table-dropdown"
+            id={col.uuid + record.uuid}
+            onBlur={this.onBlur}
+            filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+            onSelect={this.onSelectChange}
+          >
+            {subjects.map((item, i) => (<Select.Option key={i} extra={item} value={item.subjectscode}>{item.subjectscode + ' ' + item.subjectsname}</Select.Option>))}
+          </Select>
         } else {
+          let val = ''
+          if (record.subjectscode) {
+            val = (record.subjectscode || '') + ' ' + (record.subjectsname || '')
+          }
           children = <div className="content-wrap" onClick={this.focus}>{val}</div>
         }
       }
@@ -217,6 +256,7 @@
 class VoucherTable extends Component {
   static propTpyes = {
     config: PropTypes.object,        // 鑿滃崟Id
+    subjects: PropTypes.array,       // 浼氳绉戠洰
     BID: PropTypes.any,              // 涓昏〃ID
     data: PropTypes.any,             // 琛ㄦ牸鏁版嵁
     total: PropTypes.any,            // 鎬绘暟
@@ -236,17 +276,7 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { config } = this.props
-
-    let data = [
-      {remark: '鎻愮幇', subject: '1001 搴撳瓨鐜伴噾', debtor: 124, creditor: ''},
-      {remark: '璐叆鍥哄畾璧勪骇', subject: '1001 搴撳瓨鐜伴噾', debtor: '', creditor: 124},
-      {remark: '杞粨閿�鍞垚鏈�', subject: '1001 搴撳瓨鐜伴噾', debtor: -524, creditor: ''},
-      {remark: '鎻愮幇', subject: '1001 搴撳瓨鐜伴噾', debtor: 34, creditor: ''},
-    ]
-
-    data = this.initData(data)
-    data.push(this.getTotalLine(data))
+    const { config, subjects, data } = this.props
 
     let columns = [
       {
@@ -261,12 +291,13 @@
       },
       {
         title: '浼氳绉戠洰',
-        dataIndex: 'subject',
-        key: 'subject',
+        dataIndex: 'subjectscode',
+        key: 'subjectscode',
         width: '34%',
         onCell: record => ({
           record,
-          col: {uuid: 'subject', field: 'subject', tableId: config.uuid},
+          subjects,
+          col: {uuid: 'subjectscode', field: 'subjectscode', tableId: config.uuid},
         })
       },
       {
@@ -304,8 +335,7 @@
     ]
 
     this.setState({
-      data: data,
-      edData: fromJS(data).toJS(),
+      edData: this.resetData(fromJS(data).toJS()),
       columns,
       tableId: config.uuid
     })
@@ -335,8 +365,43 @@
 
   UNSAFE_componentWillReceiveProps(nextProps) {
     if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
-      this.setState({data: nextProps.data || []})
+      this.resetData(fromJS(nextProps.data).toJS())
+    } else if (!is(fromJS(this.props.subjects), fromJS(nextProps.subjects))) {
+      this.resetSubjects(nextProps.subjects)
     }
+  }
+
+  resetSubjects = (subjects) => {
+    const { config } = this.props
+    let columns = fromJS(this.state.columns).toJS()
+
+    this.setState({
+      columns: columns.map(col => {
+        if (col.key === 'subjectscode') {
+          return {
+            title: '浼氳绉戠洰',
+            dataIndex: 'subjectscode',
+            key: 'subjectscode',
+            width: '34%',
+            onCell: record => ({
+              record,
+              subjects,
+              col: {uuid: 'subjectscode', field: 'subjectscode', tableId: config.uuid},
+            })
+          }
+        }
+        return col
+      })
+    })
+  }
+
+  resetData = (data) => {
+    data = this.initData(data)
+    data.push(this.getTotalLine(data))
+
+    this.setState({
+      edData: data
+    })
   }
 
   initData = (data) => {
@@ -349,7 +414,7 @@
 
     if (_data.length < 4) {
       for (let i = _data.length - 1; i < 4; i++) {
-        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subject: '', debtor: '', creditor: ''})
+        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
       }
     }
     return _data
@@ -478,7 +543,7 @@
       MKEmitter.emit('tdFocus', 'remark' + edData[record.index + 1].uuid)
     } else {
       let _data = fromJS(edData).toJS()
-      let line = {uuid: Utils.getuuid(), index: _data.length - 1, remark: record.remark || '', subject: '', debtor: '', creditor: ''}
+      let line = {uuid: Utils.getuuid(), index: _data.length - 1, remark: record.remark || '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''}
 
       _data.splice(_data.length - 1, 0, line)
 
@@ -512,7 +577,7 @@
 
     if (_data.length < 4) {
       for (let i = _data.length - 1; i < 4; i++) {
-        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subject: '', debtor: '', creditor: ''})
+        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
       }
     }
 
@@ -535,7 +600,7 @@
     _data.pop()
 
     if (record.index === _data.length - 1) {
-      _data.push({uuid: Utils.getuuid(), index: record.index + 1, remark: '', subject: '', debtor: '', creditor: ''})
+      _data.push({uuid: Utils.getuuid(), index: record.index + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
     }
 
     _data.push(this.getTotalLine(_data))
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.scss b/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
index 5114008..4d4702a 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
@@ -141,6 +141,22 @@
       height: 60px;
     }
   }
+  .ant-select {
+    padding: 0px;
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+    .ant-select-selection {
+      height: 100%;
+      border-radius: 0;
+
+      .ant-select-arrow {
+        display: none;
+      }
+    }
+  }
   .editing_table_cell {
     .ant-input {
       padding: 0px;
@@ -181,3 +197,10 @@
     }
   }
 }
+
+.edit-table-dropdown {
+  .ant-select-dropdown-menu-item {
+    white-space: unset;
+    text-overflow: unset;
+  }
+}
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index 5c7df59..328ccb5 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -837,7 +837,7 @@
     MKEmitter.emit('resetSelectLine', MenuID, _id, _data)
   }
 
-  resetTable = (id, repage) => {
+  resetTable = (id, repage, pageIndex) => {
     const { MenuID } = this.props
 
     if (id !== MenuID) return
@@ -848,6 +848,13 @@
         activeIndex: null,
         pickup: false
       })
+    } else if (repage === 'repage') {
+      this.setState({
+        pageIndex: pageIndex,
+        selectedRowKeys: [],
+        activeIndex: null,
+        pickup: false
+      })
     } else {
       this.setState({
         pageIndex: 1,
diff --git a/src/tabviews/custom/components/share/tabtransfer/index.jsx b/src/tabviews/custom/components/share/tabtransfer/index.jsx
index 75ee5c2..aebf282 100644
--- a/src/tabviews/custom/components/share/tabtransfer/index.jsx
+++ b/src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -124,14 +124,15 @@
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
   loadmaindata = (params) => {
+    const { config } = this.props
     let BID = ''
-    let BData = window.GLOB.CacheData.get(this.props.config.$pageId)
+    let BData = window.GLOB.CacheData.get(config.$pageId)
 
     if (BData) {
       BID = BData.$BID || ''
     }
 
-    let param = getStructuredParams(params, this.props.config, BID)
+    let param = getStructuredParams(params, config, BID)
 
     Api.genericInterface(param).then(result => {
       if (result.status) {
@@ -140,6 +141,16 @@
         delete result.ErrMesg
         delete result.ErrCode
 
+        if (config.$cache) {
+          params.forEach((item) => {
+            let _data = result[item.name] || ''
+            if (_data && !Array.isArray(_data)) {
+              _data = [_data]
+            }
+            Api.writeCacheConfig(item.uuid, _data)
+          })
+        }
+
         this.setState({
           data: result
         })
diff --git a/src/tabviews/custom/components/table/base-table/index.jsx b/src/tabviews/custom/components/table/base-table/index.jsx
index 5114db7..f8f7454 100644
--- a/src/tabviews/custom/components/table/base-table/index.jsx
+++ b/src/tabviews/custom/components/table/base-table/index.jsx
@@ -126,7 +126,7 @@
       })
       
       MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
-      reset && MKEmitter.emit('resetTable', config.uuid, repage) // 鍒楄〃閲嶇疆
+      reset && MKEmitter.emit('resetTable', config.uuid, 'true') // 鍒楄〃閲嶇疆
       if (setting.$hasSyncModule) {
         MKEmitter.emit('syncBalconyData', config.uuid, [], false)
       }
@@ -157,6 +157,23 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
+      if (repage === 'false' && result.data && result.data.length === 0 && result.total > 0 && pageIndex > 1) {
+        let _pageIndex = Math.ceil(result.total / pageSize)
+
+        if (_pageIndex < pageIndex) {
+          MKEmitter.emit('resetTable', config.uuid, 'repage', _pageIndex)
+          this.setState({
+            pageIndex: _pageIndex,
+            data: [],
+            selectedData: [],
+            total: result.total
+          }, () => {
+            this.loadmaindata()
+          })
+          return
+        }
+      }
+
       if ((setting.selected !== 'false' || (setting.orisel && id)) && result.data && result.data.length > 0) {
         setTimeout(() => {
           MKEmitter.emit('mkCheckTopLine', config.uuid, id, setting.selected)
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index 03baac5..49dae01 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -186,7 +186,7 @@
         selectedData: [],
         total: 0
       })
-      reset && MKEmitter.emit('resetTable', config.uuid, repage) // 鍒楄〃閲嶇疆
+      reset && MKEmitter.emit('resetTable', config.uuid, 'true') // 鍒楄〃閲嶇疆
       return
     }
 
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 993a997..bcf4ee3 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -1203,13 +1203,21 @@
       if (item.resourceType === '1' && result[item.uuid] && result[item.uuid].length > 0) {
         let options = []
         let _map = new Map()
+        let all = false
         result[item.uuid].forEach(cell => {
           let _cell = {key: Utils.getuuid()}
 
           _cell.value = cell[item.valueField]
           _cell.label = cell[item.valueText]
 
-          if (!_cell.label && _cell.label !== 0) return
+          if (!_cell.label && _cell.label !== 0) {
+            if (!all) {
+              _cell.label = '鍏ㄩ儴'
+              all = true
+            } else {
+              return
+            }
+          }
 
           if (_map.has(_cell.value)) return
           _map.set(_cell.value, 0)
diff --git a/src/tabviews/custom/components/table/normal-table/index.jsx b/src/tabviews/custom/components/table/normal-table/index.jsx
index 87c85cb..0ffafaa 100644
--- a/src/tabviews/custom/components/table/normal-table/index.jsx
+++ b/src/tabviews/custom/components/table/normal-table/index.jsx
@@ -45,6 +45,8 @@
     statFValue: []        // 鍚堣鍊�
   }
 
+  loaded = false
+
   /**
    * @description 鍒濆鍖栧鐞�
    * 1銆� initdata 涓烘墦鍗版椂浣跨敤鐨勬暟鎹泦
@@ -84,15 +86,16 @@
       setting.orisel = true
     }
 
-    if (_config.setting.sync === 'true' && data) {
+    if (_sync && data) {
       _data = data[_config.dataName] || []
       _sync = false
-    } else if (_config.setting.sync === 'true' && initdata) {
+    } else if (_sync && initdata) {
       _data = initdata || []
       _sync = false
     }
 
     if (_data) {
+      this.loaded = true
       _data = _data.map((item, index) => {
         item.key = index
         item.$$uuid = item[_config.setting.primaryKey] || ''
@@ -201,10 +204,12 @@
       })
       
       MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
-      reset && MKEmitter.emit('resetTable', config.uuid, repage) // 鍒楄〃閲嶇疆
+      reset && MKEmitter.emit('resetTable', config.uuid, 'true') // 鍒楄〃閲嶇疆
       if (setting.$hasSyncModule) {
         MKEmitter.emit('syncBalconyData', config.uuid, [], false)
       }
+
+      this.loaded = true
       return
     }
 
@@ -234,6 +239,28 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
+      this.loaded = true
+      if (config.$cache && pageIndex === 1) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
+      if (repage === 'false' && result.data && result.data.length === 0 && result.total > 0 && pageIndex > 1) {
+        let _pageIndex = Math.ceil(result.total / pageSize)
+
+        if (_pageIndex < pageIndex) {
+          MKEmitter.emit('resetTable', config.uuid, 'repage', _pageIndex)
+          this.setState({
+            pageIndex: _pageIndex,
+            data: [],
+            selectedData: [],
+            total: result.total
+          }, () => {
+            this.loadmaindata()
+          })
+          return
+        }
+      }
+      
       if ((setting.selected !== 'false' || (setting.orisel && id)) && result.data && result.data.length > 0) {
         setTimeout(() => {
           MKEmitter.emit('mkCheckTopLine', config.uuid, id, setting.selected)
@@ -644,6 +671,8 @@
         }
       }
 
+      this.loaded = true
+
       this.setState({sync: false, data: _data})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({pageIndex: 1}, () => {
@@ -657,7 +686,7 @@
   }
 
   componentDidMount () {
-    const { config } = this.state
+    const { config, setting } = this.state
 
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
@@ -675,6 +704,35 @@
         })
       })
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        this.setState({data: res.map((item, index) => {
+          item.key = index
+          item.$$uuid = item[config.setting.primaryKey] || ''
+          item.$$key = '' + item.key + item.$$uuid
+          item.$Index = index + 1 + ''
+
+          if (config.absFields) {
+            config.absFields.forEach(f => {
+              if (!isNaN(item[f])) {
+                item[f] = Math.abs(item[f])
+              }
+            })
+          }
+
+          if (setting.controlField) {
+            if (setting.controlVal.includes(item[setting.controlField])) {
+              item.$disabled = true
+            }
+          }
+          
+          return item
+        })})
+      })
+    }
   }
 
   /**
diff --git a/src/tabviews/custom/components/timeline/normal-timeline/index.jsx b/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
index b189d5d..d8ed53e 100644
--- a/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
+++ b/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
@@ -32,6 +32,8 @@
     description: false
   }
 
+  loaded = false
+
   /**
    * @description 鍒濆鍖栧鐞�
    * 1銆� initdata 涓烘墦鍗版椂浣跨敤鐨勬暟鎹泦
@@ -66,6 +68,7 @@
     }
 
     if (_data) {
+      this.loaded = true
       _data = _data.map((item, index) => {
         item.key = index
         item.$$uuid = item[_config.setting.primaryKey] || ''
@@ -123,6 +126,20 @@
         this.loadData(true)
       })
     }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        this.setState({data: res.map((item, index) => {
+          item.key = index
+          item.$$uuid = item[config.setting.primaryKey] || ''
+          item.$Index = index + 1 + ''
+          
+          return item
+        })})
+      })
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -161,6 +178,8 @@
         item.$Index = index + 1 + ''
         return item
       })
+
+      this.loaded = true
 
       this.setState({sync: false, data: _data})
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
@@ -246,6 +265,7 @@
       this.setState({
         data: [],
       })
+      this.loaded = true
       return
     }
 
@@ -280,6 +300,11 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       this.setState({
         data: result.data.map((item, index) => {
           item.key = index
diff --git a/src/tabviews/custom/components/timeline/normal-timeline/index.scss b/src/tabviews/custom/components/timeline/normal-timeline/index.scss
index 3fecd28..38ef5b9 100644
--- a/src/tabviews/custom/components/timeline/normal-timeline/index.scss
+++ b/src/tabviews/custom/components/timeline/normal-timeline/index.scss
@@ -80,9 +80,9 @@
 
   .loading-mask {
     position: absolute;
-    left: 40px;
+    left: 0px;
     top: 0;
-    right: 40px;
+    right: 0px;
     bottom: 0px;
     display: flex;
     align-items: center;
diff --git a/src/tabviews/custom/components/tree/antd-tree/index.jsx b/src/tabviews/custom/components/tree/antd-tree/index.jsx
index a5ec5fe..688fe7a 100644
--- a/src/tabviews/custom/components/tree/antd-tree/index.jsx
+++ b/src/tabviews/custom/components/tree/antd-tree/index.jsx
@@ -34,6 +34,8 @@
     selected: false            // 閫変腑棣栬
   }
 
+  loaded = false
+
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
     let _config = fromJS(config).toJS()
@@ -52,15 +54,17 @@
       BID = BData.$BID || ''
     }
 
-    if (config.setting.sync === 'true' && data) {
+    if (_sync && data) {
       _data = data[config.dataName] || []
       _sync = false
-    } else if (config.setting.sync === 'true' && initdata) {
+    } else if (_sync && initdata) {
       _data = initdata || []
       _sync = false
     }
 
     _config.wrap.contentHeight = config.wrap.title || config.wrap.searchable === 'true' ? 'calc(100% - 45px)' : '100%'
+
+    this.loaded = _data !== null
 
     this.setState({
       selected: _config.wrap.selected === 'true',
@@ -92,6 +96,8 @@
         _data = nextProps.data[config.dataName] || []
       }
 
+      this.loaded = true
+
       this.setState({sync: false, data: _data}, () => {
         this.handleData()
       })
@@ -116,6 +122,16 @@
       this.timer = new TimerTask()
       this.timer.init(config.uuid, config.timer, config.timerRepeats, () => {
         this.loadData(true)
+      })
+    }
+
+    if (config.$cache && !this.loaded) {
+      Api.getLCacheConfig(config.uuid).then(res => {
+        if (!res || this.loaded) return
+
+        this.setState({data: res}, () => {
+          this.handleData()
+        })
       })
     }
   }
@@ -165,6 +181,7 @@
       }, () => {
         this.handleData()
       })
+      this.loaded = true
       return
     }
 
@@ -186,6 +203,11 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
+      this.loaded = true
+      if (config.$cache) {
+        Api.writeCacheConfig(config.uuid, result.data || '')
+      }
+
       this.setState({
         data: result.data,
         loading: false
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 453c221..39687e8 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -197,9 +197,10 @@
         popview = 'popview'
       }
 
-      config.interfaces = this.formatInterSetting(config.interfaces, regs)
+      config.$cache = config.cacheLocal === 'true'
 
-      config.components = this.filterComponent(config.components, roleId, window.GLOB.mkActions, balMap, skip, param, MenuID, config.interfaces, popview)
+      config.interfaces = this.formatInterSetting(config.interfaces, regs)
+      config.components = this.filterComponent(config.components, roleId, window.GLOB.mkActions, balMap, skip, param, MenuID, config.interfaces, popview, config.$cache)
       
       // 鑾峰彇涓绘悳绱㈡潯浠�
       let mainSearch = []
@@ -307,9 +308,10 @@
     }
   }
 
-  filterComponent = (components, roleId, permAction, balMap, skip, urlparam, pageId, interfaces, popview) => {
+  filterComponent = (components, roleId, permAction, balMap, skip, urlparam, pageId, interfaces, popview, cache) => {
     return components.filter(item => {
       item.$pageId = pageId
+      item.$cache = cache
       
       if (item.style && item.style.boxShadow) {
         delete item.style.hShadow
@@ -393,7 +395,7 @@
         item.subtabs = item.subtabs.map(tab => {
           tab.$pageId = pageId
 
-          tab.components = this.filterComponent(tab.components, roleId, permAction, balMap, skip, urlparam, pageId, interfaces, popview)
+          tab.components = this.filterComponent(tab.components, roleId, permAction, balMap, skip, urlparam, pageId, interfaces, popview, cache)
           return tab
         })
 
@@ -406,7 +408,7 @@
           return false
         }
 
-        item.components = this.filterComponent(item.components, roleId, permAction, balMap, skip, urlparam, pageId, interfaces, popview)
+        item.components = this.filterComponent(item.components, roleId, permAction, balMap, skip, urlparam, pageId, interfaces, popview, cache)
 
         return true
       } else if (['pie', 'bar', 'line', 'dashboard', 'scatter', 'chart'].includes(item.type)) {
@@ -988,7 +990,8 @@
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
   loadmaindata = (params) => {
-    let param = getStructuredParams(params, this.state.config, this.state.BID || '')
+    const { config } = this.state
+    let param = getStructuredParams(params, config, this.state.BID || '')
 
     this.setState({loading: true, loadingview: false})
 
@@ -998,6 +1001,16 @@
         delete result.message
         delete result.ErrMesg
         delete result.ErrCode
+
+        if (config.$cache) {
+          params.forEach((item) => {
+            let _data = result[item.name] || ''
+            if (_data && !Array.isArray(_data)) {
+              _data = [_data]
+            }
+            Api.writeCacheConfig(item.uuid, _data)
+          })
+        }
 
         this.setState({
           data: result,
@@ -1300,7 +1313,7 @@
 
     return (
       <div className={'custom-page-wrap ' + (loadingview || loading ? 'loading' : '')} id={this.state.ContainerId} style={config ? config.style : null}>
-        {(loadingview || loading) ? <Spin className="view-spin" size="large" /> : null}
+        {(loadingview || (loading && !config.$cache)) ? <Spin className="view-spin" size="large" /> : null}
         <Row className="component-wrap">{this.getComponents()}</Row>
         {config && config.interfaces.length > 0 ? <MkInterfaces BID={BID} interfaces={config.interfaces}/> : null}
         {config && window.GLOB.breakpoint ? <DebugTable /> : null}
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index 1f5597a..6862c55 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -129,7 +129,9 @@
       })
     }
 
-    config.components = this.filterComponent(config.components, roleId, balMap, param, Tab)
+    config.$cache = config.cacheLocal === 'true'
+
+    config.components = this.filterComponent(config.components, roleId, balMap, param, Tab, config.$cache)
     
     // 鑾峰彇涓绘悳绱㈡潯浠�
     let mainSearch = []
@@ -175,9 +177,10 @@
     })
   }
 
-  filterComponent = (components, roleId, balMap, urlparam, Tab) => {
+  filterComponent = (components, roleId, balMap, urlparam, Tab, cache) => {
     return components.filter(item => {
       item.$pageId = Tab.uuid
+      item.$cache = cache
       
       if (item.style && item.style.boxShadow) {
         delete item.style.hShadow
@@ -261,7 +264,7 @@
         item.subtabs = item.subtabs.map(tab => {
           tab.$pageId = Tab.uuid
 
-          tab.components = this.filterComponent(tab.components, roleId, balMap, urlparam, Tab)
+          tab.components = this.filterComponent(tab.components, roleId, balMap, urlparam, Tab, cache)
           return tab
         })
 
@@ -274,7 +277,7 @@
           return false
         }
 
-        item.components = this.filterComponent(item.components, roleId, balMap, urlparam, Tab)
+        item.components = this.filterComponent(item.components, roleId, balMap, urlparam, Tab, cache)
 
         return true
       } else if (['pie', 'bar', 'line', 'dashboard', 'scatter', 'chart'].includes(item.type)) {
@@ -754,7 +757,8 @@
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
   loadmaindata = (params) => {
-    let param = getStructuredParams(params, this.state.config, this.state.BID || '')
+    const { config } = this.state
+    let param = getStructuredParams(params, config, this.state.BID || '')
 
     this.setState({loading: true})
 
@@ -764,6 +768,16 @@
         delete result.message
         delete result.ErrMesg
         delete result.ErrCode
+
+        if (config.$cache) {
+          params.forEach((item) => {
+            let _data = result[item.name] || ''
+            if (_data && !Array.isArray(_data)) {
+              _data = [_data]
+            }
+            Api.writeCacheConfig(item.uuid, _data)
+          })
+        }
 
         this.setState({
           data: result,
@@ -1011,7 +1025,7 @@
 
     return (
       <div className={'pop-page-wrap ' + (loading ? 'loading' : '')} style={config ? config.style : null}>
-        {loading ? <Spin className="view-spin" size="large" /> : null}
+        {loading && !config.$cache ? <Spin className="view-spin" size="large" /> : null}
         <Row className="component-wrap">{this.getComponents()}</Row>
         {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
       </div>
diff --git a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
index af7f8d7..802daaf 100644
--- a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -164,7 +164,10 @@
     let _this = this
 
     let param = {
-      func: 'webapi_ChangeUser'
+      func: 'webapi_ChangeUser',
+      login_city: sessionStorage.getItem('city') || '',
+      login_id_address: sessionStorage.getItem('ipAddress') || '',
+      domain_name: window.btoa(window.encodeURIComponent(window.GLOB.host)),
     }
 
     if (this.props.BID) {
diff --git a/src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx
index cd65eaa..86891ed 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from 'react'
 import PropTypes from 'prop-types'
 import { notification } from 'antd'
-import * as XLSX from 'xlsx'
+import * as XLSX from 'sheetjs-style'
 import Utils from '@/utils/utils.js'
 import './index.scss'
 
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index 09ee076..d0cba8c 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -303,7 +303,7 @@
       })
     }
 
-    let result = getExcelInSql(btn, data, this.state.dict, (this.props.BID || ''))
+    let result = getExcelInSql(btn, data, this.state.dict, (this.props.BID || ''), this.state.primaryId)
 
     if (result.errors) {
       notification.warning({
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 8dc3084..3d93b36 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -3,7 +3,7 @@
 import moment from 'moment'
 import { is, fromJS } from 'immutable'
 import { Button, Modal, notification, message } from 'antd'
-import * as XLSX from 'xlsx'
+import * as XLSX from 'sheetjs-style'
 
 import Utils from '@/utils/utils.js'
 import options from '@/store/options.js'
@@ -602,11 +602,15 @@
         let _header = []
         let _topRow = {}
         let colwidth = []
-  
-        columns.forEach(col => {
+        let requires = []
+
+        columns.forEach((col, i) => {
           _header.push(col.Column)
           _topRow[col.Column] = col.Text
           colwidth.push({width: col.Width || 20})
+          if (col.required === 'true') {
+            requires.push(i)
+          }
         })
   
         let table = []
@@ -638,8 +642,18 @@
         })
   
         const ws = XLSX.utils.json_to_sheet(table, {header: _header, skipHeader: true})
-  
+
         ws['!cols'] = colwidth
+
+        if (requires.length) {
+          let cols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+          requires.forEach(col => {
+            if (cols[col]) {
+              ws[cols[col] + '1'].s = {font: { color: { rgb: 'F5222D' } }}
+            }
+          })
+        }
+        // ws["A1"].s = {fill: { bgColor: { rgb: "FFFFAA"  }}, font: { color: { rgb: "1890FF" } }}
   
         const wb = XLSX.utils.book_new()
         XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 48a20c1..e69e00d 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -715,6 +715,7 @@
       if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect', 'cascader'].includes(item.type) && result[item.field] && result[item.field].length > 0) {
         let options = []
         let map = new Map()
+        let all = false
         result[item.field].forEach(cell => {
           let _cell = { key: Utils.getuuid() , ParentID: ''}
 
@@ -725,7 +726,15 @@
           if (item.type !== 'checkcard') {
             _cell.value = cell[item.valueField]
             _cell.label = cell[item.valueText] + ''
-            if (!_cell.label || map.has(_cell.ParentID + _cell.value)) return
+            if (map.has(_cell.ParentID + _cell.value)) return
+            if (!_cell.label) {
+              if (!all) {
+                _cell.label = '鍏ㄩ儴'
+                all = true
+              } else {
+                return
+              }
+            }
             
             map.set(_cell.ParentID + _cell.value, 0)
           } else {
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index 9c98c03..85fbb90 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -404,6 +404,7 @@
       if (['select', 'link', 'multiselect', 'checkcard'].includes(item.type) && result[item.field] && result[item.field].length > 0) {
         let options = []
         let map = new Map()
+        let all = false
         result[item.field].forEach(cell => {
           let _item = {
             key: Utils.getuuid(),
@@ -418,7 +419,15 @@
             _item.Value = cell[item.valueField]
             _item.Text = cell[item.valueText] + ''
             
-            if (!_item.Text || map.has(_item.ParentID + _item.Value)) return
+            if (map.has(_item.ParentID + _item.Value)) return
+            if (!_item.Text) {
+              if (!all) {
+                _item.Text = '鍏ㄩ儴'
+                all = true
+              } else {
+                return
+              }
+            }
             
             map.set(_item.ParentID + _item.Value, 0)
           } else {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
index f288e7d..a4e6142 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -49,7 +49,7 @@
       _dec += ','
     }
 
-    let _sql = `Declare @${btn.sheet} table (${_dec}jskey nvarchar(50) )
+    let _sql = `Declare @${btn.sheet.replace(/@db@/ig, '')} table (${_dec}jskey nvarchar(50) )
       Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50), @retmsg nvarchar(4000),@tbid Nvarchar(512)
       Select @ErrorCode='', @retmsg=''
     `
@@ -183,7 +183,7 @@
         }
 
         param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/\$check@|@check\$/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/\$check@|@check\$/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id|typename)@/ig, `'${param.timestamp}'`)
         param.LText = param.LText.replace(/\n/g, ' ')
         
         // 澶栬仈鏁版嵁搴撴浛鎹�
@@ -298,7 +298,7 @@
           </Col>
           <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id, typename</span></Tooltip>,&nbsp;
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
               {usefulfields}
             </Form.Item>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index 947413b..5973e2d 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -250,6 +250,12 @@
       col.type = col.type || 'Nvarchar(50)'
       col.import = col.import || 'true'
       col.required = col.required || 'true'
+
+      if (col.type === 'text' || col.type === 'image') {
+        col.type = 'Nvarchar(50)'
+      } else if (col.type === 'number') {
+        col.type = 'Decimal(18,2)'
+      }
       
       if (/^Nvarchar/ig.test(col.type)) {
         col.limit = col.type.match(/\d+/)[0]
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index 6fe2b7c..8f566d2 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -37,7 +37,7 @@
         inputType: 'input',
         editable: true,
         unique: true,
-        width: '17%'
+        width: '16%'
       },
       {
         title: '鍚嶇О',
@@ -45,7 +45,7 @@
         inputType: 'input',
         editable: true,
         unique: true,
-        width: '17%'
+        width: '16%'
       },
       {
         title: '鍒楀',
@@ -54,7 +54,7 @@
         min: 5,
         max: 200,
         editable: true,
-        width: '12%',
+        width: '10%',
         render: (text) => text || 20
       },
       {
@@ -63,7 +63,7 @@
         inputType: 'select',
         editable: true,
         required: false,
-        width: '14%',
+        width: '12%',
         render: (text) => {
           if (text === 'image') {
             return '鍥剧墖'
@@ -85,7 +85,7 @@
         inputType: 'radio',
         editable: true,
         required: false,
-        width: '14%',
+        width: '12%',
         render: (text) => {
           if (text === 'true') {
             return '鏄�'
@@ -114,7 +114,7 @@
         inputType: 'radio',
         editable: true,
         required: false,
-        width: '14%',
+        width: '12%',
         render: (text) => {
           if (text !== 'false') {
             return '鏄�'
@@ -126,7 +126,19 @@
           {value: 'true', text: '鏄�'},
           {value: 'false', text: '鍚�'}
         ]
-      }
+      },
+      {
+        title: '绾㈣壊鏍囬',
+        dataIndex: 'required',
+        width: '10%',
+        editable: true,
+        inputType: 'radio',
+        render: (text, record) => record.required === 'true' ? '鏄�' : '鍚�',
+        options: [
+          {value: 'true', text: '鏄�'},
+          {value: 'false', text: '鍚�'}
+        ]
+      },
     ],
     scriptsColumns: [
       {
@@ -215,13 +227,21 @@
     if (card.intertype !== 'system') {
       _verify.enable = 'false'
     }
-    if (_verify.columns[0] && (!_verify.columns[0].type || !_verify.columns[0].output)) {
-      _verify.columns = _verify.columns.map(col => {
-        col.type = col.type || 'text'
-        col.output = col.output || 'true'
-        return col
-      })
-    }
+    _verify.columns = _verify.columns.map(col => {
+      col.type = col.type || 'text'
+      col.output = col.output || 'true'
+      col.required = col.required || 'false'
+
+      if (!['text', 'image', 'number'].includes(col.type)) {
+        if (/^Decimal/ig.test(col.type)) {
+          col.type = 'number'
+        } else {
+          col.type = 'text'
+        }
+      }
+
+      return col
+    })
 
     let defaultscript = ''
     if (!_verify.script && card.intertype === 'system') {
@@ -459,6 +479,7 @@
     values.uuid = Utils.getuuid()
     values.abs = 'false'
     values.output = 'true'
+    values.required = 'false'
     verify.columns.push(values)
 
     this.setState({
@@ -751,6 +772,7 @@
         Width: 20,
         abs: 'false',
         output: 'true',
+        required: 'false',
         type: 'text',
         uuid: Utils.getuuid()
       }
@@ -798,6 +820,7 @@
           Width: 20,
           abs: 'false',
           output: col.output || 'true',
+          required: col.required || 'false',
           type: 'text',
         }
 
@@ -995,7 +1018,7 @@
             <Button className="excel-col-add mk-red" title="娓呯┖Excel鍒�" onClick={this.clearField}>
               娓呯┖Excel鍒�
             </Button>
-            <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>濡傞渶瀵煎嚭搴忓彿锛岃浣跨敤瀛楁 $Index锛涙暟鍊肩被鍨嬪鍑烘椂鍙繘琛屾暟鎹鐞嗭紙鍙栫粷瀵瑰�笺�佷繚鐣欏皬鏁颁綅锛夈��</div>
+            <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>濡傞渶瀵煎嚭搴忓彿锛岃浣跨敤瀛楁 $Index锛涙暟鍊肩被鍨嬪鍑烘椂鍙繘琛屾暟鎹鐞嗭紙鍙栫粷瀵瑰�笺�佷繚鐣欏皬鏁颁綅锛夛紱绾㈣壊鏍囬瀵煎嚭鏃跺垪澶存枃瀛椾负绾㈣壊銆�</div>
             <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" wrappedComponentRef={(inst) => this.columnRef = inst} data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
           </TabPane>
           {card.intertype === 'system' ? <TabPane tab={
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index 3ad9a27..6588635 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -419,7 +419,11 @@
 
     let resource = this.props.form.getFieldValue('dataSource') || ''
 
-    resource = `select '' as ${field},'鍏ㄩ儴' as ${text} union all \n${resource}`
+    if (field === text) {
+      resource = `select '' as ${field} union all \n${resource}`
+    } else {
+      resource = `select '' as ${field},'鍏ㄩ儴' as ${text} union all \n${resource}`
+    }
 
     this.props.form.setFieldsValue({dataSource: resource})
   }
diff --git a/src/templates/zshare/editTable/index.scss b/src/templates/zshare/editTable/index.scss
index 7d83deb..a2f12ad 100644
--- a/src/templates/zshare/editTable/index.scss
+++ b/src/templates/zshare/editTable/index.scss
@@ -13,6 +13,9 @@
     .ant-select {
       width: 100%;
     }
+    span.ant-radio + * {
+      padding-left: 2px;
+    }
     > td {
       padding: 14px 10px;
     }
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index db416fb..4a6f1e1 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -560,7 +560,11 @@
 
     let resource = this.props.form.getFieldValue('dataSource') || ''
 
-    resource = `select '' as ${field},'鍏ㄩ儴' as ${text} union all \n${resource}`
+    if (field === text) {
+      resource = `select '' as ${field} union all \n${resource}`
+    } else {
+      resource = `select '' as ${field},'鍏ㄩ儴' as ${text} union all \n${resource}`
+    }
 
     this.props.form.setFieldsValue({dataSource: resource})
   }
diff --git a/src/utils/utils-datamanage.js b/src/utils/utils-datamanage.js
index b085f16..14883d2 100644
--- a/src/utils/utils-datamanage.js
+++ b/src/utils/utils-datamanage.js
@@ -733,7 +733,7 @@
  * @description 鐢熸垚鍗曚釜缁勪欢sPC_Get_structured_data璇锋眰鍙傛暟
  */
 export function getStructDefaultParam (component, searchlist, first) {
-  const { columns, setting, dataName, format } = component
+  const { columns, setting, dataName, format, uuid } = component
 
   let arr_field = columns.map(col => col.field)
   let _dataresource = setting.dataresource
@@ -799,6 +799,7 @@
   }
 
   return {
+    uuid: uuid,
     name: dataName,
     $name: setting.$name,
     columns: columns,
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 2a82699..e7c224d 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -844,7 +844,7 @@
  * @return {Object} dict   瀛楀吀椤�
  * @return {String} BID    涓婄骇Id
  */
-export function getExcelInSql (item, data, dict, BID) {
+export function getExcelInSql (item, data, dict, BID, primaryId) {
   let btn = item.verify
   let keys = ['delete', 'drop', 'insert', 'truncate', 'update']
   let userName = sessionStorage.getItem('User_Name') || ''
@@ -897,20 +897,30 @@
     btn.scripts.forEach(script => {
       if (script.status === 'false') return
 
+      let _sql = script.sql
+
+      _sql = _sql.replace(/@ID@/ig, `'${primaryId || ''}'`)
+      _sql = _sql.replace(/@BID@/ig, `'${BID}'`)
+      _sql = _sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+      _sql = _sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+      _sql = _sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+      _sql = _sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+      _sql = _sql.replace(/@typename@/ig, `'admin'`)
+
       if (script.position === 'init') {
         _initCustomScript += `
       /* 鑷畾涔夎剼鏈� */
-      ${script.sql}
+      ${_sql}
       `
       } else if (script.position === 'front') {
         _prevCustomScript += `
       /* 鑷畾涔夎剼鏈� */
-      ${script.sql}
+      ${_sql}
       `
       } else {
         _backCustomScript += `
       /* 鑷畾涔夎剼鏈� */
-      ${script.sql}
+      ${_sql}
       `
       }
     })
diff --git a/src/views/appmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx
index 9c4cb9c..c9b5b5b 100644
--- a/src/views/appmanage/submutilform/index.jsx
+++ b/src/views/appmanage/submutilform/index.jsx
@@ -296,7 +296,7 @@
             <Form.Item label={
               <Tooltip placement="topLeft" title="鍦ㄤ娇鐢ㄦ槑绉戜簯APP鏃讹紝鐘舵�佹爮鐨勫瓧浣撻鑹层��">
                 <QuestionCircleOutlined className="mk-form-tip" />
-                鐘舵�佹爮
+                鐘舵�佹爮鏂囧瓧
               </Tooltip>
             }>
               {getFieldDecorator('statusBarColor', {
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index 5855e79..8a0d939 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -69,11 +69,8 @@
    * @param {Object} param 鐢ㄦ埛鍚嶅瘑鐮佺瓑淇℃伅
    */
   async loginsubmit (param) {
-    let city = sessionStorage.getItem('city') || ''
-    let ipAddress = sessionStorage.getItem('ipAddress') || ''
-
     // 鐧诲綍鎻愪氦
-    let res = await Api.getusermsg(param.username, param.password, false, ipAddress, city)
+    let res = await Api.getusermsg(param.username, param.password, false)
     if (res.status) {
       if (res.check_mob) {
         let loginWays = this.state.loginWays.filter(item => item.type === 'sms_vcode')
@@ -195,11 +192,8 @@
   }
 
   async phoneloginsubmit (param) {
-    let city = sessionStorage.getItem('city') || ''
-    let ipAddress = sessionStorage.getItem('ipAddress') || ''
-
     // 鐧诲綍鎻愪氦
-    let res = await Api.getphoneusermsg(param.phone, param.vercode, false, ipAddress, city)
+    let res = await Api.getphoneusermsg(param.phone, param.vercode, false)
     if (res.status) {
       sessionStorage.setItem('UserID', res.UserID)
       sessionStorage.setItem('LoginUID', res.LoginUID)
@@ -326,6 +320,10 @@
     //   if (!res || !res.ip) return
     //   sessionStorage.setItem('ipAddress', res.ip)
     // })
+
+    setTimeout(() => {
+      Api.delCacheConfig()
+    }, 50)
     if (window.GLOB.filter) {
       let view = document.getElementById('mk-login-view')
       

--
Gitblit v1.8.0