From 5186227a467bd34dc253e64b23bc96d3a07bb399 Mon Sep 17 00:00:00 2001
From: zhangzengfei <zhangzengfei@smartai.com>
Date: 星期三, 17 十一月 2021 17:39:53 +0800
Subject: [PATCH] 添加用户权限控制

---
 src/api/package.js                           |    8 
 src/plugins/echarts.js                       |    6 
 src/views/login/index.vue                    |   23 
 src/layouts/components/VabAvatar/index.vue   |  144 ++
 src/plugins/element.js                       |   12 
 src/layouts/components/VabNavBar/index.vue   |   35 
 .eslintrc.js                                 |   10 
 src/components/VabUpload/index.vue           |  300 +++---
 src/utils/errorLog.js                        |   30 
 src/views/user/components/UserEdit.vue       |  116 ++
 src/views/user/index.vue                     |  254 +++++
 src/config/net.config.js                     |   14 
 src/config/permission.js                     |   81 
 src/store/modules/user.js                    |   98 +
 src/api/user.js                              |   46 
 src/config/setting.config.js                 |   44 
 src/router/index.js                          |   91 +
 src/utils/handleRoutes.js                    |   38 
 src/utils/validate.js                        |   76 
 src/utils/request.js                         |  114 +-
 /dev/null                                    |   43 
 src/components/VabSnow/index.vue             |  115 +-
 src/components/VabProfile/index.vue          |  450 ++++----
 src/views/project/components/ProjectEdit.vue |   13 
 src/plugins/index.js                         |   30 
 src/components/SelectTree/index.vue          |  292 +++---
 src/views/project/index.vue                  |   38 
 src/components/VabCharge/index.vue           |  296 +++---
 src/store/modules/routes.js                  |   28 
 29 files changed, 1,679 insertions(+), 1,166 deletions(-)

diff --git a/.eslintrc.js b/.eslintrc.js
index ab6565e..7652ede 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -8,24 +8,24 @@
   env: {
     node: true,
   },
-  extends: ['plugin:vue/recommended', '@vue/prettier'],
+  extends: ["plugin:vue/recommended", "@vue/prettier"],
   rules: {
     // 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
     // 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
     // 'vue/no-v-html': 'off',
   },
   parserOptions: {
-    parser: 'babel-eslint',
+    parser: "babel-eslint",
   },
   overrides: [
     {
       files: [
-        '**/__tests__/*.{j,t}s?(x)',
-        '**/tests/unit/**/*.spec.{j,t}s?(x)',
+        "**/__tests__/*.{j,t}s?(x)",
+        "**/tests/unit/**/*.spec.{j,t}s?(x)",
       ],
       env: {
         jest: true,
       },
     },
   ],
-}
+};
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 0099bf4..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 good luck
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/mock/controller/ad.js b/mock/controller/ad.js
deleted file mode 100644
index b45a0dd..0000000
--- a/mock/controller/ad.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const data = [
-  {
-    title: '寤哄厷鐧惧勾鎯婂枩绂忓埄锛屼粯璐圭増鏈拱涓�寰椾簩鍏ㄥ勾鏈�浣庝环锛岀偣鎴戣喘涔�',
-    url: 'http://vue-admin-beautiful.com/authorization',
-  },
-  /*   {
-    title: 'Admin Pro 3.0浠樿垂鐗堟湰宸插彂甯冿紝澧炲姞澶氶」璐村績鍔熻兘锛岀偣鎴戞彁鍓嶄綋楠�',
-    url: 'https://chu1204505056.gitee.io/admin-pro?hmsr=homeAd&hmpl=&hmcu=&hmkw=&hmci=',
-  },
-  {
-    title: 'Admin Plus 3.0鍐呮祴鐗堟湰宸插彂甯冿紝澧炲姞澶氶」璐村績鍔熻兘锛岀偣鎴戞彁鍓嶄綋楠�',
-    url: 'https://chu1204505056.gitee.io/admin-plus?hmsr=homeAd&hmpl=&hmcu=&hmkw=&hmci=',
-  },
-  {
-    title: 'vue-admin-beautiful锛坅ntdv锛� vue3.0鐗堟湰宸插彂甯冿紝鐐规垜鎻愬墠浣撻獙',
-    url: 'http://vue-admin-beautiful.com/vue-admin-beautiful-antdv?hmsr=homeAd&hmpl=&hmcu=&hmkw=&hmci=',
-  },
-  {
-    title: 'vue-admin-beautiful锛坋lement-plus锛� vue3.0鐗堟湰宸插彂甯冿紝鐐规垜鎻愬墠浣撻獙',
-    url: 'https://chu1204505056.gitee.io/admin-plus?hmsr=homeAd&hmpl=&hmcu=&hmkw=&hmci=',
-  },
-  {
-    title:
-      '绋嬪簭鏃犲浗鐣岋紝浣嗙▼搴忓憳鏈夊浗鐣岋紝涓浗鍥藉灏婁弗涓嶅鎸戣锛屽鏋滄偍鍦ㄧ壒娈婃椂鏈熺户缁喘涔癏M銆佽�愬厠銆侀樋杩揪鏂瓑鍝佺墝閭d箞鎮ㄥ皢鏃犳潈缁х画浣跨敤Vab',
-    url: 'https://chu1204505056.gitee.io/admin-pro?hmsr=homeAd&hmpl=&hmcu=&hmkw=&hmci=',
-  }, */
-]
-module.exports = [
-  {
-    url: '/ad/getList',
-    type: 'get',
-    response() {
-      return {
-        code: 200,
-        msg: 'success',
-        data,
-      }
-    },
-  },
-]
diff --git a/mock/controller/changeLog.js b/mock/controller/changeLog.js
deleted file mode 100644
index 6fbb88d..0000000
--- a/mock/controller/changeLog.js
+++ /dev/null
@@ -1,250 +0,0 @@
-const data = [
-  {
-    content: '鍦╣ithub涓婅幏寰椾簡绗竴涓猻tar锛屾劅鎭╀竴浣嶅悕鍙獴equiet2014鐨刧ithub鐢ㄦ埛',
-    timestamp: '2020-03-23',
-  },
-  {
-    content: '澧炲姞鏇存崲涓婚鍔熻兘',
-    timestamp: '2020-04-10',
-  },
-  {
-    content: '澶у箙绮剧畝浠g爜',
-    timestamp: '2020-04-14',
-  },
-  {
-    content: '淇缇ゅ弸鍙嶉鐨刡ug',
-    timestamp: '2020-04-16',
-  },
-  {
-    content: '鍓旈櫎maptalks',
-    timestamp: '2020-04-17',
-  },
-  {
-    content:
-      '鎹㈣绗︾粺涓�淇敼涓簂f 鏀寔鑻规灉 linux windows鍗忓悓寮�鍙� 寮哄埗寮�鍚渶涓ユ牸eslint瑙勫垯 涓嶈鍝� 涓ユ牸鏄湁濂藉鐨�',
-    timestamp: '2020-04-17',
-  },
-  {
-    content: '褰诲簳瀹屾垚鎵嬫満绔�傞厤,璁板綍杩欎竴澶╃啲澶滃埌浜嗘櫄涓婁笁鐐�',
-    timestamp: '2020-04-18',
-  },
-  {
-    content:
-      '鍒犻櫎babel-polyfill 鎻愰珮鎵撳寘閫熷害 鍑忓皯鍘嬬缉浣撶Н锛堟斁寮僫e鏄繖涓」鐩仛鍑虹殑鏈�浼熷ぇ鐨勫喅瀹氾級',
-    timestamp: '2020-04-18',
-  },
-  {
-    content: '婧愮爜绮剧畝鑷�800k',
-    timestamp: '2020-04-19',
-  },
-  {
-    content: '娣诲姞瑙嗛鎾斁鍣ㄧ粍浠�',
-    timestamp: '2020-04-20',
-  },
-  {
-    content: '淇璺敱鎳掑姞杞� 瀹屽杽涓婚閰嶈壊',
-    timestamp: '2020-04-22',
-  },
-  {
-    content: '淇鍏ㄥ眬axios鎷︽埅 鍔犲揩鍔ㄧ敾灞曠ず鏁堟灉 淇敼鐧诲綍椤垫牱寮�',
-    timestamp: '2020-04-24',
-  },
-  {
-    content: '绠�鍖栨潈闄愪笌鐧诲綍閫昏緫 鏇存柊mockServer',
-    timestamp: '2020-04-25',
-  },
-  {
-    content: '浼樺寲鐧诲綍閫�鍑洪�昏緫 浠g爜鏇存竻鏅� 閫�鍑轰笉鍐嶉噸杞界綉椤� 鏀逛负閲嶈浇璺敱褰㈠紡',
-    timestamp: '2020-04-26',
-  },
-  {
-    content: '鏃犵鐨勬寚璐e彧浼氳鎴戞洿鍔犲姫鍔� 淇sidebar 绠�鍖杙ermission',
-    timestamp: '2020-04-28',
-  },
-  {
-    content: '鍙堟槸涓�涓繁澶� 瀹炵幇浜嗚〃鏍煎鍒犳敼鏌ョ殑涓�閿敓鎴�',
-    timestamp: '2020-04-30',
-  },
-  {
-    content: '澶у箙浼樺寲tagsview鏍囩鍔ㄧ敾',
-    timestamp: '2020-05-02',
-  },
-  {
-    content: '涓夌鍥炬爣缁勪欢瀹炵幇mock妯℃嫙鍒嗛〉',
-    timestamp: '2020-05-03',
-  },
-  {
-    content: '娣诲姞浜唌arkdown缂栬緫鍣ㄧ粍浠�',
-    timestamp: '2020-05-04',
-  },
-  {
-    content: '娣诲姞stylelint-plus鑷姩瑙勬暣鎺掑簭鏍峰紡',
-    timestamp: '2020-05-06',
-  },
-  {
-    content: '娣诲姞鍟嗗煄妯℃澘',
-    timestamp: '2020-05-12',
-  },
-  {
-    content: 'github鏍囨槦瓒呰繃1000 鎰熸仼',
-    timestamp: '2020-05-13',
-  },
-  {
-    content: '娣诲姞楠岃瘉鐮佺粍浠�',
-    timestamp: '2020-05-14',
-  },
-  {
-    content: '淇妯悜鑿滃崟bug',
-    timestamp: '2020-05-16',
-  },
-  {
-    content: '鍙堣浜洪獋浜� 鎸哄ソ鐨� 璁╂垜涓嬪畾鍐冲績閲嶅啓浜唗absBar',
-    timestamp: '2020-05-20',
-  },
-  {
-    content: '浠縜nt-design 娣诲姞闆姳灞�',
-    timestamp: '2020-05-26',
-  },
-  {
-    content: '娣诲姞浜哄憳绠$悊妯″潡',
-    timestamp: '2020-06-02',
-  },
-  {
-    content: 'github鏍囨槦瓒呰繃2000 鎰熸仼',
-    timestamp: '2020-06-03',
-  },
-  {
-    content: '娣诲姞鐐叿鍦板浘缁勪欢',
-    timestamp: '2020-06-11',
-  },
-  {
-    content: '鎶界鏇村鍏叡閰嶇疆锛屾鏋朵娇鐢ㄦ洿椤烘墜',
-    timestamp: '2020-06-19',
-  },
-  {
-    content: '褰诲簳瀹屾垚浜唗absBar澶氭爣绛鹃〉鐨勯噸鏋�',
-    timestamp: '2020-06-22',
-  },
-  {
-    content: '鎰熸仼github鏍囨槦杩�3.0K 绁濆ぇ瀹剁鍗堣妭蹇箰',
-    timestamp: '2020-06-25',
-  },
-  {
-    content: '褰诲簳閲嶆瀯浜哠ideBar涓嶵opBar 澶у箙绮剧畝dom娓叉煋閫昏緫 鍏ㄧ悆棣栧彂',
-    timestamp: '2020-06-25',
-  },
-  {
-    content: '娣诲姞鑿滃崟绠$悊',
-    timestamp: '2020-07-7',
-  },
-  {
-    content: '棣栨閲囩敤sass-loader 9.0鍐欐硶锛屾劅璋ithub鐢ㄦ埛 shaonialife',
-    timestamp: '2020-07-7',
-  },
-  {
-    content: '娣诲姞vue-amap缁勪欢',
-    timestamp: '2020-07-11',
-  },
-  {
-    content: '淇敼zx-layouts寮曞叆鏂瑰紡',
-    timestamp: '2020-07-15',
-  },
-  {
-    content:
-      '璁板綍杩欎竴澶﹙ue-admin-beautiful鍦ㄦ彃浠跺競鍦恒�佺櫨搴﹀凡鑺辫垂瓒呰繃1涓囧厓骞垮憡璐圭敤锛屽笇鏈涗竴鍒囬兘鍊煎緱',
-    timestamp: '2020-07-18',
-  },
-  {
-    content: '涓婚閰嶇疆娣诲姞缁胯崼鑽夊満銆佽崳鑰�鍏歌棌銆佹殫榛戜箣瀛愭ā寮�',
-    timestamp: '2020-07-18',
-  },
-  {
-    content: '鍏ㄥ眬axios璇锋眰鍏ㄩ潰鏀寔Status Code鎷︽埅澶勭悊',
-    timestamp: '2020-07-29',
-  },
-  {
-    content: '閲嶆瀯鍏ㄥ眬loadding鍔犺浇浠g爜',
-    timestamp: '2020-07-31',
-  },
-  {
-    content: '鍗囩骇stylelint鑷姩鎺掑簭鍔熻兘',
-    timestamp: '2020-08-25',
-  },
-  {
-    content: '淇瑙嗛鎾斁鍣ㄧ粍浠堕噸杞借矾鐢卞け鏁堢殑bug',
-    timestamp: '2020-09-03',
-  },
-  {
-    content: '淇鏋佷釜鍒儏鍐礽mage-loader鎵撳寘鎶ラ敊',
-    timestamp: '2020-09-18',
-  },
-  {
-    content: '鍏ㄧ綉棣栦釜鍩轰簬vue3.0寮�鍙戠殑admin妗嗘灦宸插彂甯冿紝鍏蜂綋璇疯闂甮ithub',
-    timestamp: '2020-09-22',
-  },
-  {
-    content: '瀹屽杽璺敱鍚庣娓叉煋鏂规锛屽純鐢ㄤ箣鍓嶅啓娉�',
-    timestamp: '2020-09-30',
-  },
-  {
-    content: '澶х増鏈凯浠o紝璇峰叧娉╣ithub tag',
-    timestamp: '2020-09-30',
-  },
-  /* {
-    content:
-      "闈㈠鑷О鍔犳嬁澶у崕浜虹殑鎹曡泧鑰呰浣滆�卨aike9m鐨勫彂甯栬瘚姣侊紝鍜屼汉韬敾鍑伙紝鏈兂鍘荤煡涔庢壘浠栫悊璁猴紝鍙浣曚粬鐨勭煡涔庡凡缁忕敱浜庣粡甯稿彂甯冮敊璇█璁鸿瀹樻柟灏佸彿浜唄ttps://www.zhihu.com/people/laike9m锛屾棦鐒惰嚜宸遍兘涓嶆槸涓浗浜轰簡锛屽氨涓嶈濡勫姞鎻f祴鍥戒骇鐨勫紑婧愰」鐩簡锛屼竴鍒囬兘浜ょ粰鏃堕棿鍚э紝鍚庢潵鎴戦噴鎬�浜嗭紝laike9m銆丆ruii杩欑兢浜轰笉姝㈡槸鎶归粦鎴戠殑妗嗘灦锛岀敋鑷宠繕鍘绘姽榛戜腑鍥芥皯钀ヤ紒涓氱殑浣间郊鑰呭崕涓猴紝鍏呮弧浜嗘棤濂堝晩锛屼篃璁稿彧鏈夊彂甯冭繖鏍风殑瑷�璁猴紝浠栦滑鐨勭洰鐨勬墠鑳借揪鍒版妸 https://github.com/evil-huawei/evil-huawei",
-    timestamp: "2020-10-01",
-  }, */
-  {
-    content: '鍑屾櫒涓ょ偣锛屾垜绱簡锛岀Щ闄ゆ棤鐢ㄧ粍浠讹紝绮剧畝package',
-    timestamp: '2020-10-02',
-  },
-  {
-    content: '瀵屾枃鏈紪杈戝櫒鏀寔绮剧粏鍖栭厤缃�',
-    timestamp: '2020-10-20',
-  },
-  {
-    content: '鍏叡甯冨眬鏀寔鑷姩瀵煎嚭',
-    timestamp: '2020-10-23',
-  },
-  {
-    content: '閬僵娣诲姞楂樻柉妯$硦',
-    timestamp: '2020-10-25',
-  },
-  {
-    content: 'vue3.0 + element-plus鐗堟湰姝e紡涓婄嚎',
-    timestamp: '2020-12-5',
-  },
-  {
-    content: '瀹屾垚棣栭〉閲嶆瀯锛岃窡杩沞charts 5.0',
-    timestamp: '2020-12-7',
-  },
-  {
-    content: '鏇存柊sass鐗堟湰鑷虫渶鏂�',
-    timestamp: '2021-1-7',
-  },
-  {
-    content: '鏇存柊vue-echarts鐗堟湰鑷虫渶鏂�,options鍙樻洿涓簅ption',
-    timestamp: '2021-2-23',
-  },
-  {
-    content:
-      '寮�婧愮増鍝佺墝鍚嶅崌绾т负vue-admin-beautiful-pro锛屼粯璐圭増vue2.x鍝佺墝鍗囩骇涓篈dmin Pro锛屼粯璐圭増vue3.x鍝佺墝鍚嶅崌绾т负Admin Plus',
-    timestamp: '鏈�杩戞洿鏂�',
-  },
-]
-
-module.exports = [
-  {
-    url: '/changeLog/getList',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: 999,
-        data: data,
-      }
-    },
-  },
-]
diff --git a/mock/controller/colorfulIcon.js b/mock/controller/colorfulIcon.js
deleted file mode 100644
index 8d7625f..0000000
--- a/mock/controller/colorfulIcon.js
+++ /dev/null
@@ -1,324 +0,0 @@
-const data = [
-  'alphabetical_sorting',
-  'alphabetical_sorting',
-  'alarm_clock',
-  'area_chart',
-  'approval',
-  'answers',
-  'approve',
-  'assistant',
-  'automotive',
-  'automatic',
-  'bad_decision',
-  'bar_chart',
-  'bearish',
-  'biomass',
-  'biohazard',
-  'binoculars',
-  'bookmark',
-  'briefcase',
-  'biotech',
-  'broken_link',
-  'business',
-  'bullish',
-  'business_contact',
-  'businesswoman',
-  'cable_release',
-  'calculator',
-  'businessman',
-  'calendar',
-  'butting_in',
-  'call_transfer',
-  'callback',
-  'camcorder',
-  'camera',
-  'camcorder_pro',
-  'cancel',
-  'camera_addon',
-  'camera_identificatio',
-  'capacitor',
-  'candle_sticks',
-  'checkmark',
-  'circuit',
-  'charge_battery',
-  'clear_filters',
-  'clapperboard',
-  'clock',
-  'close_up_mode',
-  'collaboration',
-  'cell_phone',
-  'collapse',
-  'collect',
-  'cloth',
-  'combo_chart',
-  'comments',
-  'conference_call',
-  'compact_camera',
-  'contacts',
-  'copyleft',
-  'copyright',
-  'crystal_oscillator',
-  'cursor',
-  'currency_exchange',
-  'customer_support',
-  'dam',
-  'data_backup',
-  'data_configuration',
-  'data_encryption',
-  'data_protection',
-  'data_recovery',
-  'database',
-  'data_sheet',
-  'debt',
-  'decision',
-  'delete_column',
-  'delete_database',
-  'department',
-  'delete_row',
-  'deployment',
-  'dislike',
-  'disapprove',
-  'disclaimer',
-  'display',
-  'document',
-  'do_not_insert',
-  'do_not_mix',
-  'do_not_inhale',
-  'donate',
-  'down',
-  'doughnut_chart',
-  'down_left',
-  'down_right',
-  'download',
-  'edit_image',
-  'electrical_sensor',
-  'electrical_threshold',
-  'electricity',
-  'electro_devices',
-  'electronics',
-  'empty_battery',
-  'empty_filter',
-  'empty_trash',
-  'end_call',
-  'engineering',
-  'entering_heaven_aliv',
-  'expand',
-  'export',
-  'expired',
-  'factory',
-  'factory_breakdown',
-  'external',
-  'faq',
-  'feed_in',
-  'file',
-  'feedback',
-  'film',
-  'filled_filter',
-  'filing_cabinet',
-  'film_reel',
-  'flash_auto',
-  'fine_print',
-  'flash_off',
-  'flash_on',
-  'flow_chart',
-  'folder',
-  'frame',
-  'full_battery',
-  'full_trash',
-  'gallery',
-  'generic_sorting_asc',
-  'generic_sorting_desc',
-  'genealogy',
-  'globe',
-  'good_decision',
-  'headset',
-  'grid',
-  'graduation_cap',
-  'heat_map',
-  'high_priority',
-  'high_battery',
-  'image_file',
-  'home',
-  'idea',
-  'import',
-  'in_transit',
-  'integrated_webcam',
-  'inspection',
-  'invite',
-  'internal',
-  'ipad',
-  'info',
-  'iphone',
-  'kindle',
-  'key',
-  'landscape',
-  'left',
-  'left_down',
-  'left_up',
-  'leave',
-  'like_placeholder',
-  'light_at_the_end_of_',
-  'library',
-  'line_chart',
-  'link',
-  'like',
-  'lock',
-  'list',
-  'lock_landscape',
-  'low_battery',
-  'lock_portrait',
-  'low_priority',
-  'make_decision',
-  'medium_priority',
-  'manager',
-  'menu',
-  'middle_battery',
-  'minus',
-  'missed_call',
-  'mind_map',
-  'mms',
-  'multiple_cameras',
-  'money_transfer',
-  'music',
-  'multiple_devices',
-  'multiple_smartphones',
-  'multiple_inputs',
-  'negative_dynamic',
-  'neutral_decision',
-  'night_landscape',
-  'news',
-  'neutral_trading',
-  'night_portrait',
-  'no_idea',
-  'next',
-  'no_video',
-  'nook',
-  'ok',
-  'org_unit',
-  'opened_folder',
-  'old_time_camera',
-  'online_support',
-  'organization',
-  'package',
-  'paid',
-  'parallel_tasks',
-  'overtime',
-  'panorama',
-  'phone',
-  'phone_android',
-  'photo_reel',
-  'pie_chart',
-  'picture',
-  'planner',
-  'plus',
-  'podium_with_audience',
-  'podium_without_speak',
-  'podium_with_speaker',
-  'previous',
-  'portrait_mode',
-  'positive_dynamic',
-  'privacy',
-  'process',
-  'puzzle',
-  'questions',
-  'print',
-  'radar_plot',
-  'rating',
-  'ratings',
-  'reading',
-  'redo',
-  'reading_ebook',
-  'refresh',
-  'registered_trademark',
-  'right',
-  'reuse',
-  'remove_image',
-  'right_down',
-  'right_up',
-  'rotate_to_portrait',
-  'rules',
-  'rotate_camera',
-  'rotate_to_landscape',
-  'ruler',
-  'scatter_plot',
-  'search',
-  'safe',
-  'self_service_kiosk',
-  'selfie',
-  'serial_tasks',
-  'sales_performance',
-  'settings',
-  'services',
-  'share',
-  'shipped',
-  'sim_card',
-  'shop',
-  'service_mark',
-  'sim_card_chip',
-  'signature',
-  'smartphone_tablet',
-  'sound_recording_copy',
-  'sms',
-  'speaker',
-  'slr_back_side',
-  'start',
-  'stack_of_photos',
-  'statistics',
-  'sports_mode',
-  'support',
-  'synchronize',
-  'switch_camera',
-  'survey',
-  'tablet_android',
-  'template',
-  'trademark',
-  'todo_list',
-  'touchscreen_smartpho',
-  'timeline',
-  'tree_structure',
-  'undo',
-  'up_left',
-  'two_smartphones',
-  'unlock',
-  'up',
-  'up_right',
-  'upload',
-  'video_call',
-  'video_file',
-  'view_details',
-  'video_projector',
-  'vip',
-  'voice_presentation',
-  'webcam',
-  'voicemail',
-  'workflow',
-  'about',
-  'accept_database',
-  'add_image',
-  'add_column',
-  'add_database',
-  'add_row',
-]
-module.exports = [
-  {
-    url: '/colorfulIcon/getList',
-    type: 'post',
-    response(config) {
-      const { title, pageNo = 1, pageSize = 72 } = config.body
-      let mockList = data.filter((item) => {
-        if (title && item.indexOf(title) < 0) return false
-        return true
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: mockList.length,
-        data: pageList,
-      }
-    },
-  },
-]
diff --git a/mock/controller/goodsList.js b/mock/controller/goodsList.js
deleted file mode 100644
index 82176a3..0000000
--- a/mock/controller/goodsList.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const { mock } = require('mockjs')
-
-const List = []
-const count = 999
-let num = 0
-for (let i = 0; i < count; i++) {
-  List.push(
-    mock({
-      uuid: '@uuid',
-      image: `https://picsum.photos/300/600?random=${num++}`,
-      title: '@ctitle',
-      description: '@csentence',
-      link: 'https://www.baidu.com',
-      price: '@integer(100, 500)',
-      'status|1': [1, 0],
-      'isRecommend|1': [1, 0],
-    })
-  )
-}
-
-module.exports = [
-  {
-    url: '/goodsList/getList',
-    type: 'post',
-    response(config) {
-      const { title = '', pageNo = 1, pageSize = 20 } = config.body
-      let mockList = List.filter((item) => {
-        if (title && item.title.indexOf(title) < 0) return false
-        return true
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: count,
-        data: pageList,
-      }
-    },
-  },
-]
diff --git a/mock/controller/icon.js b/mock/controller/icon.js
deleted file mode 100644
index 365400a..0000000
--- a/mock/controller/icon.js
+++ /dev/null
@@ -1,985 +0,0 @@
-const data = [
-  'air-freshener',
-  'align-center',
-  'align-justify',
-  'align-left',
-  'align-right',
-  'allergies',
-  'ambulance',
-  'american-sign-language-interpreting',
-  'anchor',
-  'angle-double-down',
-  'angle-double-left',
-  'angle-double-right',
-  'angle-double-up',
-  'angle-down',
-  'angle-left',
-  'angle-right',
-  'angle-up',
-  'angry',
-  'ankh',
-  'apple-alt',
-  'archive',
-  'archway',
-  'arrow-alt-circle-down',
-  'arrow-alt-circle-left',
-  'arrow-alt-circle-right',
-  'arrow-alt-circle-up',
-  'arrow-circle-down',
-  'arrow-circle-left',
-  'arrow-circle-right',
-  'arrow-circle-up',
-  'arrow-down',
-  'arrow-left',
-  'arrow-right',
-  'arrow-up',
-  'arrows-alt',
-  'arrows-alt-h',
-  'arrows-alt-v',
-  'assistive-listening-systems',
-  'asterisk',
-  'at',
-  'atlas',
-  'atom',
-  'audio-description',
-  'award',
-  'baby',
-  'baby-carriage',
-  'backspace',
-  'backward',
-  'bacon',
-  'bahai',
-  'balance-scale',
-  'balance-scale-left',
-  'balance-scale-right',
-  'ban',
-  'band-aid',
-  'barcode',
-  'bars',
-  'baseball-ball',
-  'basketball-ball',
-  'bath',
-  'battery-empty',
-  'battery-full',
-  'battery-half',
-  'battery-quarter',
-  'battery-three-quarters',
-  'bed',
-  'beer',
-  'bell',
-  'bell-slash',
-  'bezier-curve',
-  'bible',
-  'bicycle',
-  'biking',
-  'binoculars',
-  'biohazard',
-  'birthday-cake',
-  'blender',
-  'blender-phone',
-  'blind',
-  'blog',
-  'bold',
-  'bolt',
-  'bomb',
-  'bone',
-  'bong',
-  'book',
-  'book-dead',
-  'book-medical',
-  'book-open',
-  'book-reader',
-  'bookmark',
-  'border-all',
-  'border-none',
-  'border-style',
-  'bowling-ball',
-  'box',
-  'box-open',
-  'boxes',
-  'braille',
-  'brain',
-  'bread-slice',
-  'briefcase',
-  'briefcase-medical',
-  'broadcast-tower',
-  'broom',
-  'brush',
-  'bug',
-  'building',
-  'bullhorn',
-  'bullseye',
-  'burn',
-  'bus',
-  'bus-alt',
-  'business-time',
-  'calculator',
-  'calendar',
-  'calendar-alt',
-  'calendar-check',
-  'calendar-day',
-  'calendar-minus',
-  'calendar-plus',
-  'calendar-times',
-  'calendar-week',
-  'camera',
-  'camera-retro',
-  'campground',
-  'candy-cane',
-  'cannabis',
-  'capsules',
-  'car',
-  'car-alt',
-  'car-battery',
-  'car-crash',
-  'car-side',
-  'caravan',
-  'caret-down',
-  'caret-left',
-  'caret-right',
-  'caret-square-down',
-  'caret-square-left',
-  'caret-square-right',
-  'caret-square-up',
-  'caret-up',
-  'carrot',
-  'cart-arrow-down',
-  'cart-plus',
-  'cash-register',
-  'cat',
-  'certificate',
-  'chair',
-  'chalkboard',
-  'chalkboard-teacher',
-  'charging-station',
-  'chart-area',
-  'chart-bar',
-  'chart-line',
-  'chart-pie',
-  'check',
-  'check-circle',
-  'check-double',
-  'check-square',
-  'cheese',
-  'chess',
-  'chess-bishop',
-  'chess-board',
-  'chess-king',
-  'chess-knight',
-  'chess-pawn',
-  'chess-queen',
-  'chess-rook',
-  'chevron-circle-down',
-  'chevron-circle-left',
-  'chevron-circle-right',
-  'chevron-circle-up',
-  'chevron-down',
-  'chevron-left',
-  'chevron-right',
-  'chevron-up',
-  'child',
-  'church',
-  'circle',
-  'circle-notch',
-  'city',
-  'clinic-medical',
-  'clipboard',
-  'clipboard-check',
-  'clipboard-list',
-  'clock',
-  'clone',
-  'closed-captioning',
-  'cloud',
-  'cloud-download-alt',
-  'cloud-meatball',
-  'cloud-moon',
-  'cloud-moon-rain',
-  'cloud-rain',
-  'cloud-showers-heavy',
-  'cloud-sun',
-  'cloud-sun-rain',
-  'cloud-upload-alt',
-  'cocktail',
-  'code',
-  'code-branch',
-  'coffee',
-  'cog',
-  'cogs',
-  'coins',
-  'columns',
-  'comment',
-  'comment-alt',
-  'comment-dollar',
-  'comment-dots',
-  'comment-medical',
-  'comment-slash',
-  'comments',
-  'comments-dollar',
-  'compact-disc',
-  'compass',
-  'compress',
-  'compress-alt',
-  'compress-arrows-alt',
-  'concierge-bell',
-  'cookie',
-  'cookie-bite',
-  'copy',
-  'copyright',
-  'couch',
-  'credit-card',
-  'crop',
-  'crop-alt',
-  'cross',
-  'crosshairs',
-  'crow',
-  'crown',
-  'crutch',
-  'cube',
-  'cubes',
-  'cut',
-  'database',
-  'deaf',
-  'democrat',
-  'desktop',
-  'dharmachakra',
-  'diagnoses',
-  'dice',
-  'dice-d20',
-  'dice-d6',
-  'dice-five',
-  'dice-four',
-  'dice-one',
-  'dice-six',
-  'dice-three',
-  'dice-two',
-  'digital-tachograph',
-  'directions',
-  'divide',
-  'dizzy',
-  'dna',
-  'dog',
-  'dollar-sign',
-  'dolly',
-  'dolly-flatbed',
-  'donate',
-  'door-closed',
-  'door-open',
-  'dot-circle',
-  'dove',
-  'download',
-  'drafting-compass',
-  'dragon',
-  'draw-polygon',
-  'drum',
-  'drum-steelpan',
-  'drumstick-bite',
-  'dumbbell',
-  'dumpster',
-  'dumpster-fire',
-  'dungeon',
-  'edit',
-  'egg',
-  'eject',
-  'ellipsis-h',
-  'ellipsis-v',
-  'envelope',
-  'envelope-open',
-  'envelope-open-text',
-  'envelope-square',
-  'equals',
-  'eraser',
-  'ethernet',
-  'euro-sign',
-  'exchange-alt',
-  'exclamation',
-  'exclamation-circle',
-  'exclamation-triangle',
-  'expand',
-  'expand-alt',
-  'expand-arrows-alt',
-  'external-link-alt',
-  'external-link-square-alt',
-  'eye',
-  'eye-dropper',
-  'eye-slash',
-  'fan',
-  'fast-backward',
-  'fast-forward',
-  'fax',
-  'feather',
-  'feather-alt',
-  'female',
-  'fighter-jet',
-  'file',
-  'file-alt',
-  'file-archive',
-  'file-audio',
-  'file-code',
-  'file-contract',
-  'file-csv',
-  'file-download',
-  'file-excel',
-  'file-export',
-  'file-image',
-  'file-import',
-  'file-invoice',
-  'file-invoice-dollar',
-  'file-medical',
-  'file-medical-alt',
-  'file-pdf',
-  'file-powerpoint',
-  'file-prescription',
-  'file-signature',
-  'file-upload',
-  'file-video',
-  'file-word',
-  'fill',
-  'fill-drip',
-  'film',
-  'filter',
-  'fingerprint',
-  'fire',
-  'fire-alt',
-  'fire-extinguisher',
-  'first-aid',
-  'fish',
-  'fist-raised',
-  'flag',
-  'flag-checkered',
-  'flag-usa',
-  'flask',
-  'flushed',
-  'folder',
-  'folder-minus',
-  'folder-open',
-  'folder-plus',
-  'font',
-  'football-ball',
-  'forward',
-  'frog',
-  'frown',
-  'frown-open',
-  'funnel-dollar',
-  'futbol',
-  'gamepad',
-  'gas-pump',
-  'gavel',
-  'gem',
-  'genderless',
-  'ghost',
-  'gift',
-  'gifts',
-  'glass-cheers',
-  'glass-martini',
-  'glass-martini-alt',
-  'glass-whiskey',
-  'glasses',
-  'globe',
-  'globe-africa',
-  'globe-americas',
-  'globe-asia',
-  'globe-europe',
-  'golf-ball',
-  'gopuram',
-  'graduation-cap',
-  'greater-than',
-  'greater-than-equal',
-  'grimace',
-  'grin',
-  'grin-alt',
-  'grin-beam',
-  'grin-beam-sweat',
-  'grin-hearts',
-  'grin-squint',
-  'grin-squint-tears',
-  'grin-stars',
-  'grin-tears',
-  'grin-tongue',
-  'grin-tongue-squint',
-  'grin-tongue-wink',
-  'grin-wink',
-  'grip-horizontal',
-  'grip-lines',
-  'grip-lines-vertical',
-  'grip-vertical',
-  'guitar',
-  'h-square',
-  'hamburger',
-  'hammer',
-  'hamsa',
-  'hand-holding',
-  'hand-holding-heart',
-  'hand-holding-usd',
-  'hand-lizard',
-  'hand-middle-finger',
-  'hand-paper',
-  'hand-peace',
-  'hand-point-down',
-  'hand-point-left',
-  'hand-point-right',
-  'hand-point-up',
-  'hand-pointer',
-  'hand-rock',
-  'hand-scissors',
-  'hand-spock',
-  'hands',
-  'hands-helping',
-  'handshake',
-  'hanukiah',
-  'hard-hat',
-  'hashtag',
-  'hat-cowboy',
-  'hat-cowboy-side',
-  'hat-wizard',
-  'hdd',
-  'heading',
-  'headphones',
-  'headphones-alt',
-  'headset',
-  'heart',
-  'heart-broken',
-  'heartbeat',
-  'helicopter',
-  'highlighter',
-  'hiking',
-  'hippo',
-  'history',
-  'hockey-puck',
-  'holly-berry',
-  'home',
-  'horse',
-  'horse-head',
-  'hospital',
-  'hospital-alt',
-  'hospital-symbol',
-  'hot-tub',
-  'hotdog',
-  'hotel',
-  'hourglass',
-  'hourglass-end',
-  'hourglass-half',
-  'hourglass-start',
-  'house-damage',
-  'hryvnia',
-  'i-cursor',
-  'ice-cream',
-  'icicles',
-  'icons',
-  'id-badge',
-  'id-card',
-  'id-card-alt',
-  'igloo',
-  'image',
-  'images',
-  'inbox',
-  'indent',
-  'industry',
-  'infinity',
-  'info',
-  'info-circle',
-  'italic',
-  'jedi',
-  'joint',
-  'journal-whills',
-  'kaaba',
-  'key',
-  'keyboard',
-  'khanda',
-  'kiss',
-  'kiss-beam',
-  'kiss-wink-heart',
-  'kiwi-bird',
-  'landmark',
-  'language',
-  'laptop',
-  'laptop-code',
-  'laptop-medical',
-  'laugh',
-  'laugh-beam',
-  'laugh-squint',
-  'laugh-wink',
-  'layer-group',
-  'leaf',
-  'lemon',
-  'less-than',
-  'less-than-equal',
-  'level-down-alt',
-  'level-up-alt',
-  'life-ring',
-  'lightbulb',
-  'link',
-  'lira-sign',
-  'list',
-  'list-alt',
-  'list-ol',
-  'list-ul',
-  'location-arrow',
-  'lock',
-  'lock-open',
-  'long-arrow-alt-down',
-  'long-arrow-alt-left',
-  'long-arrow-alt-right',
-  'long-arrow-alt-up',
-  'low-vision',
-  'luggage-cart',
-  'magic',
-  'magnet',
-  'mail-bulk',
-  'male',
-  'map',
-  'map-marked',
-  'map-marked-alt',
-  'map-marker',
-  'map-marker-alt',
-  'map-pin',
-  'map-signs',
-  'marker',
-  'mars',
-  'mars-double',
-  'mars-stroke',
-  'mars-stroke-h',
-  'mars-stroke-v',
-  'mask',
-  'medal',
-  'medkit',
-  'meh',
-  'meh-blank',
-  'meh-rolling-eyes',
-  'memory',
-  'menorah',
-  'mercury',
-  'meteor',
-  'microchip',
-  'microphone',
-  'microphone-alt',
-  'microphone-alt-slash',
-  'microphone-slash',
-  'microscope',
-  'minus',
-  'minus-circle',
-  'minus-square',
-  'mitten',
-  'mobile',
-  'mobile-alt',
-  'money-bill',
-  'money-bill-alt',
-  'money-bill-wave',
-  'money-bill-wave-alt',
-  'money-check',
-  'money-check-alt',
-  'monument',
-  'moon',
-  'mortar-pestle',
-  'mosque',
-  'motorcycle',
-  'mountain',
-  'mouse',
-  'mouse-pointer',
-  'mug-hot',
-  'music',
-  'network-wired',
-  'neuter',
-  'newspaper',
-  'not-equal',
-  'notes-medical',
-  'object-group',
-  'object-ungroup',
-  'oil-can',
-  'om',
-  'otter',
-  'outdent',
-  'pager',
-  'paint-brush',
-  'paint-roller',
-  'palette',
-  'pallet',
-  'paper-plane',
-  'paperclip',
-  'parachute-box',
-  'paragraph',
-  'parking',
-  'passport',
-  'pastafarianism',
-  'paste',
-  'pause',
-  'pause-circle',
-  'paw',
-  'peace',
-  'pen',
-  'pen-alt',
-  'pen-fancy',
-  'pen-nib',
-  'pen-square',
-  'pencil-alt',
-  'pencil-ruler',
-  'people-carry',
-  'pepper-hot',
-  'percent',
-  'percentage',
-  'person-booth',
-  'phone',
-  'phone-alt',
-  'phone-slash',
-  'phone-square',
-  'phone-square-alt',
-  'phone-volume',
-  'photo-video',
-  'piggy-bank',
-  'pills',
-  'pizza-slice',
-  'place-of-worship',
-  'plane',
-  'plane-arrival',
-  'plane-departure',
-  'play',
-  'play-circle',
-  'plug',
-  'plus',
-  'plus-circle',
-  'plus-square',
-  'podcast',
-  'poll',
-  'poll-h',
-  'poo',
-  'poo-storm',
-  'poop',
-  'portrait',
-  'pound-sign',
-  'power-off',
-  'pray',
-  'praying-hands',
-  'prescription',
-  'prescription-bottle',
-  'prescription-bottle-alt',
-  'print',
-  'procedures',
-  'project-diagram',
-  'puzzle-piece',
-  'qrcode',
-  'question',
-  'question-circle',
-  'quidditch',
-  'quote-left',
-  'quote-right',
-  'quran',
-  'radiation',
-  'radiation-alt',
-  'rainbow',
-  'random',
-  'receipt',
-  'record-vinyl',
-  'recycle',
-  'redo',
-  'redo-alt',
-  'registered',
-  'remove-format',
-  'reply',
-  'reply-all',
-  'republican',
-  'restroom',
-  'retweet',
-  'ribbon',
-  'ring',
-  'road',
-  'robot',
-  'rocket',
-  'route',
-  'rss',
-  'rss-square',
-  'ruble-sign',
-  'ruler',
-  'ruler-combined',
-  'ruler-horizontal',
-  'ruler-vertical',
-  'running',
-  'rupee-sign',
-  'sad-cry',
-  'sad-tear',
-  'satellite',
-  'satellite-dish',
-  'save',
-  'school',
-  'screwdriver',
-  'scroll',
-  'sd-card',
-  'search',
-  'search-dollar',
-  'search-location',
-  'search-minus',
-  'search-plus',
-  'seedling',
-  'server',
-  'shapes',
-  'share',
-  'share-alt',
-  'share-alt-square',
-  'share-square',
-  'shekel-sign',
-  'shield-alt',
-  'ship',
-  'shipping-fast',
-  'shoe-prints',
-  'shopping-bag',
-  'shopping-basket',
-  'shopping-cart',
-  'shower',
-  'shuttle-van',
-  'sign',
-  'sign-in-alt',
-  'sign-language',
-  'sign-out-alt',
-  'signal',
-  'signature',
-  'sim-card',
-  'sitemap',
-  'skating',
-  'skiing',
-  'skiing-nordic',
-  'skull',
-  'skull-crossbones',
-  'slash',
-  'sleigh',
-  'sliders-h',
-  'smile',
-  'smile-beam',
-  'smile-wink',
-  'smog',
-  'smoking',
-  'smoking-ban',
-  'sms',
-  'snowboarding',
-  'snowflake',
-  'snowman',
-  'snowplow',
-  'socks',
-  'solar-panel',
-  'sort',
-  'sort-alpha-down',
-  'sort-alpha-down-alt',
-  'sort-alpha-up',
-  'sort-alpha-up-alt',
-  'sort-amount-down',
-  'sort-amount-down-alt',
-  'sort-amount-up',
-  'sort-amount-up-alt',
-  'sort-down',
-  'sort-numeric-down',
-  'sort-numeric-down-alt',
-  'sort-numeric-up',
-  'sort-numeric-up-alt',
-  'sort-up',
-  'spa',
-  'space-shuttle',
-  'spell-check',
-  'spider',
-  'spinner',
-  'splotch',
-  'spray-can',
-  'square',
-  'square-full',
-  'square-root-alt',
-  'stamp',
-  'star',
-  'star-and-crescent',
-  'star-half',
-  'star-half-alt',
-  'star-of-david',
-  'star-of-life',
-  'step-backward',
-  'step-forward',
-  'stethoscope',
-  'sticky-note',
-  'stop',
-  'stop-circle',
-  'stopwatch',
-  'store',
-  'store-alt',
-  'stream',
-  'street-view',
-  'strikethrough',
-  'stroopwafel',
-  'subscript',
-  'subway',
-  'suitcase',
-  'suitcase-rolling',
-  'sun',
-  'superscript',
-  'surprise',
-  'swatchbook',
-  'swimmer',
-  'swimming-pool',
-  'synagogue',
-  'sync',
-  'sync-alt',
-  'syringe',
-  'table',
-  'table-tennis',
-  'tablet',
-  'tablet-alt',
-  'tablets',
-  'tachometer-alt',
-  'tag',
-  'tags',
-  'tape',
-  'tasks',
-  'taxi',
-  'teeth',
-  'teeth-open',
-  'temperature-high',
-  'temperature-low',
-  'tenge',
-  'terminal',
-  'text-height',
-  'text-width',
-  'th',
-  'th-large',
-  'th-list',
-  'theater-masks',
-  'thermometer',
-  'thermometer-empty',
-  'thermometer-full',
-  'thermometer-half',
-  'thermometer-quarter',
-  'thermometer-three-quarters',
-  'thumbs-down',
-  'thumbs-up',
-  'thumbtack',
-  'ticket-alt',
-  'times',
-  'times-circle',
-  'tint',
-  'tint-slash',
-  'tired',
-  'toggle-off',
-  'toggle-on',
-  'toilet',
-  'toilet-paper',
-  'toolbox',
-  'tools',
-  'tooth',
-  'torah',
-  'torii-gate',
-  'tractor',
-  'trademark',
-  'traffic-light',
-  'trailer',
-  'train',
-  'tram',
-  'transgender',
-  'transgender-alt',
-  'trash',
-  'trash-alt',
-  'trash-restore',
-  'trash-restore-alt',
-  'tree',
-  'trophy',
-  'truck',
-  'truck-loading',
-  'truck-monster',
-  'truck-moving',
-  'truck-pickup',
-  'tshirt',
-  'tty',
-  'tv',
-  'umbrella',
-  'umbrella-beach',
-  'underline',
-  'undo',
-  'undo-alt',
-  'universal-access',
-  'university',
-  'unlink',
-  'unlock',
-  'unlock-alt',
-  'upload',
-  'user',
-  'user-alt',
-  'user-alt-slash',
-  'user-astronaut',
-  'user-check',
-  'user-circle',
-  'user-clock',
-  'user-cog',
-  'user-edit',
-  'user-friends',
-  'user-graduate',
-  'user-injured',
-  'user-lock',
-  'user-md',
-  'user-minus',
-  'user-ninja',
-  'user-nurse',
-  'user-plus',
-  'user-secret',
-  'user-shield',
-  'user-slash',
-  'user-tag',
-  'user-tie',
-  'user-times',
-  'users',
-  'users-cog',
-  'utensil-spoon',
-  'utensils',
-  'vector-square',
-  'venus',
-  'venus-double',
-  'venus-mars',
-  'vial',
-  'vials',
-  'video',
-  'video-slash',
-  'vihara',
-  'voicemail',
-  'volleyball-ball',
-  'volume-down',
-  'volume-mute',
-  'volume-off',
-  'volume-up',
-  'vote-yea',
-  'vr-cardboard',
-  'walking',
-  'wallet',
-  'warehouse',
-  'water',
-  'wave-square',
-  'weight',
-  'weight-hanging',
-  'wheelchair',
-  'wifi',
-  'wind',
-  'window-close',
-  'window-maximize',
-  'window-minimize',
-  'window-restore',
-  'wine-bottle',
-  'wine-glass',
-  'wine-glass-alt',
-  'won-sign',
-  'wrench',
-  'x-ray',
-  'yen-sign',
-  'yin-yang',
-]
-module.exports = [
-  {
-    url: '/icon/getList',
-    type: 'post',
-    response(config) {
-      const { title, pageNo = 1, pageSize = 72 } = config.body
-      let mockList = data.filter((item) => {
-        if (title && item.indexOf(title) < 0) return false
-        return true
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: mockList.length,
-        data: pageList,
-      }
-    },
-  },
-]
diff --git a/mock/controller/menuManagement.js b/mock/controller/menuManagement.js
deleted file mode 100644
index b86a178..0000000
--- a/mock/controller/menuManagement.js
+++ /dev/null
@@ -1,51 +0,0 @@
-module.exports = [
-  {
-    url: '/menuManagement/getTree',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: 999,
-        data: [
-          {
-            id: 'root',
-            label: '鍏ㄩ儴瑙掕壊',
-            children: [
-              {
-                id: '@id',
-                permission: 'admin',
-                label: 'admin瑙掕壊',
-              },
-              {
-                id: '@id',
-                permission: 'editor',
-                label: 'editor瑙掕壊',
-              },
-            ],
-          },
-        ],
-      }
-    },
-  },
-  {
-    url: '/menuManagement/doEdit',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙淇濆瓨鎴愬姛',
-      }
-    },
-  },
-  {
-    url: '/menuManagement/doDelete',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙鍒犻櫎鎴愬姛',
-      }
-    },
-  },
-]
diff --git a/mock/controller/notice.js b/mock/controller/notice.js
deleted file mode 100644
index 1ec6104..0000000
--- a/mock/controller/notice.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const data = [
-  {
-    title:
-      '娓╅Θ鎻愮ず锛氶泦鎴愮増铏藉姛鑳戒赴瀵岋紝浣嗗啑浣欎緷璧栬繃澶氾紝寤鸿寮�鍙戞椂浣跨敤鍩虹鐗堣繘琛屽紑鍙戯紝 寤哄厷鐧惧勾鎯婂枩绂忓埄锛屼拱涓�寰椾簩锛屽叏骞存渶浣庝环锛屼竴骞翠粎姝や竴娆★細<a target="_blank" href="http://vue-admin-beautiful.com/authorization">鐐规垜鑾峰彇浼樻儬绂忓埄</a>',
-    closable: false,
-    type: 'success',
-  },
-  {
-    title:
-      '浣滆�呭瘎璇細鎰熻阿Star锛屾劅鎭╃浉閬囷紝鎰夸笘闂寸編濂戒笌鎴戜滑鐜幆鐩告墸锛屽姞娌癸紒灞忓箷鍓嶇殑鎴戜滑锛屾墦鐮存姊忥紝鍧氬畧鍒濆績銆傚叾瀹炰汉鐢熸敼鍙樺懡杩愮殑鏈轰細骞舵病鏈夊お澶氾紝鎴戜滑骞朵笉鏄笉浼樼锛屾垜浠篃骞朵笉鏄竴鏃犳槸澶勶紝鎴戜滑涔熷笇鏈涢┗瓒冲北宸呰浼椾汉浠版湜锛屼篃璁告垜浠己灏戠殑鍙槸涓�涓満浼氾紝缂哄皯鐨勫彧鏄敓鍛戒腑鐨勫甯堬紝鎴戝笇鏈涜繖涓鏋跺府鍔╁埌鏇村鐨勪汉锛屽笇鏈涙湁涓�澶╋紝鎴戜滑闈㈣瘯鐨勬椂鍊欎笉鍐嶈儐鎬紝甯屾湜鏈変竴澶╁埆浜虹湅鍒扮殑涓嶄粎浠呮槸浣犵殑鍔姏锛岃繕鏈変綘鐨勫姛鎴愬悕灏憋紝鍑轰汉澶村湴銆�',
-    closable: false,
-    type: 'warning',
-  },
-  {
-    title:
-      '闅忕瑪锛氭垜涓�鐩村湪瀵绘壘寮�婧愮殑鐪熻皼锛屾垜涓�鐩村啀鎯充粈涔堟槸寮�婧愶紝鎴戜竴寮�濮嬭寰楀厤璐瑰氨鏄紑婧愶紝濂藉儚鍙堜笉鏄�傛垜鐞嗚В鐨勫紑婧愭槸锛氫綘涔熷紑婧愶紝鎴戜篃寮�婧愶紝澶у涓�璧疯础鐚紝鐩镐簰甯姪銆傛垜鏈�鎷呭績鐨勪簨鎯呮槸锛氭垜涓�涓皬浜虹墿锛屽幓浼哄�欎竴浼楃殑浼告墜鍏氾紝鎴戞兂锛岃繖涓嶆槸寮�婧愯鏈夌殑姘涘洿銆傛垜杩樺お骞磋交锛屼笉鎳備粈涔堟槸鏍煎眬锛屾垜鍙煡閬擄紝鏃犵鐨勫府鍔╀粬浜猴紝鑳界粰鎴戝甫鏉ュ揩涔愶紝鍗翠笉鑳界粰鎴戝甫鏉ユ敹鍏ワ紝褰撶劧锛屾湁鏃跺�欙紝蹇箰瀵规垜鏉ヨ灏卞凡缁忚冻澶熶簡銆傚彲鎯滄垜鏄竴涓汉锛屾病鏈夌簿鍔涘府鍔╁埌姣忎竴涓汉锛屽彲鎯滆繖涓笘鐣岄渶瑕佽禋閽憋紝鎵嶈兘杩囦笂骞冲嚒鐨勭敓娲伙紝鍙儨浜嗘垜鐨勬ⅵ鎯筹紝杩欎釜鐗╂妯祦鐨勬椂浠o紝鐞嗘兂涓讳箟鐨勬垜浠紝鍗充娇鍐呭績鍧氬喅濡傞搧锛屼篃浼间箮瀵告闅捐銆�',
-    closable: false,
-    type: 'success',
-  },
-]
-module.exports = [
-  {
-    url: '/notice/getList',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: 'success',
-        data,
-      }
-    },
-  },
-]
diff --git a/mock/controller/personalCenter.js b/mock/controller/personalCenter.js
deleted file mode 100644
index 0db25e7..0000000
--- a/mock/controller/personalCenter.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const { mock } = require('mockjs')
-
-module.exports = [
-  {
-    url: '/personalCenter/getList',
-    type: 'post',
-    response(config) {
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: 999,
-        data: mock({
-          'data|10': [
-            {
-              id: '@id',
-            },
-          ],
-        }).data,
-      }
-    },
-  },
-  {
-    url: '/personalCenter/doEdit',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙淇濆瓨鎴愬姛',
-      }
-    },
-  },
-  {
-    url: '/personalCenter/doDelete',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙鍒犻櫎鎴愬姛',
-      }
-    },
-  },
-]
diff --git a/mock/controller/remixIcon.js b/mock/controller/remixIcon.js
deleted file mode 100644
index db299ce..0000000
--- a/mock/controller/remixIcon.js
+++ /dev/null
@@ -1,2294 +0,0 @@
-const data = [
-  '24-hours-fill',
-  '24-hours-line',
-  '4k-fill',
-  '4k-line',
-  'a-b',
-  'account-box-fill',
-  'account-box-line',
-  'account-circle-fill',
-  'account-circle-line',
-  'account-pin-box-fill',
-  'account-pin-box-line',
-  'account-pin-circle-fill',
-  'account-pin-circle-line',
-  'add-box-fill',
-  'add-box-line',
-  'add-circle-fill',
-  'add-circle-line',
-  'add-fill',
-  'add-line',
-  'admin-fill',
-  'admin-line',
-  'airplay-fill',
-  'airplay-line',
-  'alarm-fill',
-  'alarm-line',
-  'alarm-warning-fill',
-  'alarm-warning-line',
-  'album-fill',
-  'album-line',
-  'alert-fill',
-  'alert-line',
-  'aliens-fill',
-  'aliens-line',
-  'align-bottom',
-  'align-center',
-  'align-justify',
-  'align-left',
-  'align-right',
-  'align-top',
-  'align-vertically',
-  'alipay-fill',
-  'alipay-line',
-  'amazon-fill',
-  'amazon-line',
-  'anchor-fill',
-  'anchor-line',
-  'ancient-gate-fill',
-  'ancient-gate-line',
-  'ancient-pavilion-fill',
-  'ancient-pavilion-line',
-  'android-fill',
-  'android-line',
-  'angularjs-fill',
-  'angularjs-line',
-  'anticlockwise-2-fill',
-  'anticlockwise-2-line',
-  'anticlockwise-fill',
-  'anticlockwise-line',
-  'app-store-fill',
-  'app-store-line',
-  'apple-fill',
-  'apple-line',
-  'apps-2-fill',
-  'apps-2-line',
-  'apps-fill',
-  'apps-line',
-  'archive-drawer-fill',
-  'archive-drawer-line',
-  'archive-fill',
-  'archive-line',
-  'arrow-down-circle-fill',
-  'arrow-down-circle-line',
-  'arrow-down-fill',
-  'arrow-down-line',
-  'arrow-down-s-fill',
-  'arrow-down-s-line',
-  'arrow-drop-down-fill',
-  'arrow-drop-down-line',
-  'arrow-drop-left-fill',
-  'arrow-drop-left-line',
-  'arrow-drop-right-fill',
-  'arrow-drop-right-line',
-  'arrow-drop-up-fill',
-  'arrow-drop-up-line',
-  'arrow-go-back-fill',
-  'arrow-go-back-line',
-  'arrow-go-forward-fill',
-  'arrow-go-forward-line',
-  'arrow-left-circle-fill',
-  'arrow-left-circle-line',
-  'arrow-left-down-fill',
-  'arrow-left-down-line',
-  'arrow-left-fill',
-  'arrow-left-line',
-  'arrow-left-right-fill',
-  'arrow-left-right-line',
-  'arrow-left-s-fill',
-  'arrow-left-s-line',
-  'arrow-left-up-fill',
-  'arrow-left-up-line',
-  'arrow-right-circle-fill',
-  'arrow-right-circle-line',
-  'arrow-right-down-fill',
-  'arrow-right-down-line',
-  'arrow-right-fill',
-  'arrow-right-line',
-  'arrow-right-s-fill',
-  'arrow-right-s-line',
-  'arrow-right-up-fill',
-  'arrow-right-up-line',
-  'arrow-up-circle-fill',
-  'arrow-up-circle-line',
-  'arrow-up-down-fill',
-  'arrow-up-down-line',
-  'arrow-up-fill',
-  'arrow-up-line',
-  'arrow-up-s-fill',
-  'arrow-up-s-line',
-  'artboard-2-fill',
-  'artboard-2-line',
-  'artboard-fill',
-  'artboard-line',
-  'article-fill',
-  'article-line',
-  'aspect-ratio-fill',
-  'aspect-ratio-line',
-  'asterisk',
-  'at-fill',
-  'at-line',
-  'attachment-2',
-  'attachment-fill',
-  'attachment-line',
-  'auction-fill',
-  'auction-line',
-  'award-fill',
-  'award-line',
-  'baidu-fill',
-  'baidu-line',
-  'ball-pen-fill',
-  'ball-pen-line',
-  'bank-card-2-fill',
-  'bank-card-2-line',
-  'bank-card-fill',
-  'bank-card-line',
-  'bank-fill',
-  'bank-line',
-  'bar-chart-2-fill',
-  'bar-chart-2-line',
-  'bar-chart-box-fill',
-  'bar-chart-box-line',
-  'bar-chart-fill',
-  'bar-chart-grouped-fill',
-  'bar-chart-grouped-line',
-  'bar-chart-horizontal-fill',
-  'bar-chart-horizontal-line',
-  'bar-chart-line',
-  'barcode-box-fill',
-  'barcode-box-line',
-  'barcode-fill',
-  'barcode-line',
-  'barricade-fill',
-  'barricade-line',
-  'base-station-fill',
-  'base-station-line',
-  'basketball-fill',
-  'basketball-line',
-  'battery-2-charge-fill',
-  'battery-2-charge-line',
-  'battery-2-fill',
-  'battery-2-line',
-  'battery-charge-fill',
-  'battery-charge-line',
-  'battery-fill',
-  'battery-line',
-  'battery-low-fill',
-  'battery-low-line',
-  'battery-saver-fill',
-  'battery-saver-line',
-  'battery-share-fill',
-  'battery-share-line',
-  'bear-smile-fill',
-  'bear-smile-line',
-  'behance-fill',
-  'behance-line',
-  'bell-fill',
-  'bell-line',
-  'bike-fill',
-  'bike-line',
-  'bilibili-fill',
-  'bilibili-line',
-  'bill-fill',
-  'bill-line',
-  'billiards-fill',
-  'billiards-line',
-  'bit-coin-fill',
-  'bit-coin-line',
-  'blaze-fill',
-  'blaze-line',
-  'bluetooth-connect-fill',
-  'bluetooth-connect-line',
-  'bluetooth-fill',
-  'bluetooth-line',
-  'blur-off-fill',
-  'blur-off-line',
-  'body-scan-fill',
-  'body-scan-line',
-  'bold',
-  'book-2-fill',
-  'book-2-line',
-  'book-3-fill',
-  'book-3-line',
-  'book-fill',
-  'book-line',
-  'book-mark-fill',
-  'book-mark-line',
-  'book-open-fill',
-  'book-open-line',
-  'book-read-fill',
-  'book-read-line',
-  'booklet-fill',
-  'booklet-line',
-  'bookmark-2-fill',
-  'bookmark-2-line',
-  'bookmark-3-fill',
-  'bookmark-3-line',
-  'bookmark-fill',
-  'bookmark-line',
-  'boxing-fill',
-  'boxing-line',
-  'braces-fill',
-  'braces-line',
-  'brackets-fill',
-  'brackets-line',
-  'briefcase-2-fill',
-  'briefcase-2-line',
-  'briefcase-3-fill',
-  'briefcase-3-line',
-  'briefcase-4-fill',
-  'briefcase-4-line',
-  'briefcase-5-fill',
-  'briefcase-5-line',
-  'briefcase-fill',
-  'briefcase-line',
-  'bring-forward',
-  'bring-to-front',
-  'broadcast-fill',
-  'broadcast-line',
-  'brush-2-fill',
-  'brush-2-line',
-  'brush-3-fill',
-  'brush-3-line',
-  'brush-4-fill',
-  'brush-4-line',
-  'brush-fill',
-  'brush-line',
-  'bubble-chart-fill',
-  'bubble-chart-line',
-  'bug-2-fill',
-  'bug-2-line',
-  'bug-fill',
-  'bug-line',
-  'building-2-fill',
-  'building-2-line',
-  'building-3-fill',
-  'building-3-line',
-  'building-4-fill',
-  'building-4-line',
-  'building-fill',
-  'building-line',
-  'bus-2-fill',
-  'bus-2-line',
-  'bus-fill',
-  'bus-line',
-  'bus-wifi-fill',
-  'bus-wifi-line',
-  'cactus-fill',
-  'cactus-line',
-  'cake-2-fill',
-  'cake-2-line',
-  'cake-3-fill',
-  'cake-3-line',
-  'cake-fill',
-  'cake-line',
-  'calculator-fill',
-  'calculator-line',
-  'calendar-2-fill',
-  'calendar-2-line',
-  'calendar-check-fill',
-  'calendar-check-line',
-  'calendar-event-fill',
-  'calendar-event-line',
-  'calendar-fill',
-  'calendar-line',
-  'calendar-todo-fill',
-  'calendar-todo-line',
-  'camera-2-fill',
-  'camera-2-line',
-  'camera-3-fill',
-  'camera-3-line',
-  'camera-fill',
-  'camera-lens-fill',
-  'camera-lens-line',
-  'camera-line',
-  'camera-off-fill',
-  'camera-off-line',
-  'camera-switch-fill',
-  'camera-switch-line',
-  'capsule-fill',
-  'capsule-line',
-  'car-fill',
-  'car-line',
-  'car-washing-fill',
-  'car-washing-line',
-  'caravan-fill',
-  'caravan-line',
-  'cast-fill',
-  'cast-line',
-  'cellphone-fill',
-  'cellphone-line',
-  'celsius-fill',
-  'celsius-line',
-  'centos-fill',
-  'centos-line',
-  'character-recognition-fill',
-  'character-recognition-line',
-  'charging-pile-2-fill',
-  'charging-pile-2-line',
-  'charging-pile-fill',
-  'charging-pile-line',
-  'chat-1-fill',
-  'chat-1-line',
-  'chat-2-fill',
-  'chat-2-line',
-  'chat-3-fill',
-  'chat-3-line',
-  'chat-4-fill',
-  'chat-4-line',
-  'chat-check-fill',
-  'chat-check-line',
-  'chat-delete-fill',
-  'chat-delete-line',
-  'chat-download-fill',
-  'chat-download-line',
-  'chat-follow-up-fill',
-  'chat-follow-up-line',
-  'chat-forward-fill',
-  'chat-forward-line',
-  'chat-heart-fill',
-  'chat-heart-line',
-  'chat-history-fill',
-  'chat-history-line',
-  'chat-new-fill',
-  'chat-new-line',
-  'chat-off-fill',
-  'chat-off-line',
-  'chat-poll-fill',
-  'chat-poll-line',
-  'chat-private-fill',
-  'chat-private-line',
-  'chat-quote-fill',
-  'chat-quote-line',
-  'chat-settings-fill',
-  'chat-settings-line',
-  'chat-smile-2-fill',
-  'chat-smile-2-line',
-  'chat-smile-3-fill',
-  'chat-smile-3-line',
-  'chat-smile-fill',
-  'chat-smile-line',
-  'chat-upload-fill',
-  'chat-upload-line',
-  'chat-voice-fill',
-  'chat-voice-line',
-  'check-double-fill',
-  'check-double-line',
-  'check-fill',
-  'check-line',
-  'checkbox-blank-circle-fill',
-  'checkbox-blank-circle-line',
-  'checkbox-blank-fill',
-  'checkbox-blank-line',
-  'checkbox-circle-fill',
-  'checkbox-circle-line',
-  'checkbox-fill',
-  'checkbox-indeterminate-fill',
-  'checkbox-indeterminate-line',
-  'checkbox-line',
-  'checkbox-multiple-blank-fill',
-  'checkbox-multiple-blank-line',
-  'checkbox-multiple-fill',
-  'checkbox-multiple-line',
-  'china-railway-fill',
-  'china-railway-line',
-  'chrome-fill',
-  'chrome-line',
-  'clapperboard-fill',
-  'clapperboard-line',
-  'clipboard-fill',
-  'clipboard-line',
-  'clockwise-2-fill',
-  'clockwise-2-line',
-  'clockwise-fill',
-  'clockwise-line',
-  'close-circle-fill',
-  'close-circle-line',
-  'close-fill',
-  'close-line',
-  'closed-captioning-fill',
-  'closed-captioning-line',
-  'cloud-fill',
-  'cloud-line',
-  'cloud-off-fill',
-  'cloud-off-line',
-  'cloud-windy-fill',
-  'cloud-windy-line',
-  'cloudy-2-fill',
-  'cloudy-2-line',
-  'cloudy-fill',
-  'cloudy-line',
-  'code-box-fill',
-  'code-box-line',
-  'code-fill',
-  'code-line',
-  'code-s-fill',
-  'code-s-line',
-  'code-s-slash-fill',
-  'code-s-slash-line',
-  'code-view',
-  'codepen-fill',
-  'codepen-line',
-  'coin-fill',
-  'coin-line',
-  'coins-fill',
-  'coins-line',
-  'collage-fill',
-  'collage-line',
-  'command-fill',
-  'command-line',
-  'community-fill',
-  'community-line',
-  'compass-2-fill',
-  'compass-2-line',
-  'compass-3-fill',
-  'compass-3-line',
-  'compass-4-fill',
-  'compass-4-line',
-  'compass-discover-fill',
-  'compass-discover-line',
-  'compass-fill',
-  'compass-line',
-  'compasses-2-fill',
-  'compasses-2-line',
-  'compasses-fill',
-  'compasses-line',
-  'computer-fill',
-  'computer-line',
-  'contacts-book-2-fill',
-  'contacts-book-2-line',
-  'contacts-book-fill',
-  'contacts-book-line',
-  'contacts-book-upload-fill',
-  'contacts-book-upload-line',
-  'contacts-fill',
-  'contacts-line',
-  'contrast-2-fill',
-  'contrast-2-line',
-  'contrast-drop-2-fill',
-  'contrast-drop-2-line',
-  'contrast-drop-fill',
-  'contrast-drop-line',
-  'contrast-fill',
-  'contrast-line',
-  'copper-coin-fill',
-  'copper-coin-line',
-  'copper-diamond-fill',
-  'copper-diamond-line',
-  'copyleft-fill',
-  'copyleft-line',
-  'copyright-fill',
-  'copyright-line',
-  'coreos-fill',
-  'coreos-line',
-  'coupon-2-fill',
-  'coupon-2-line',
-  'coupon-3-fill',
-  'coupon-3-line',
-  'coupon-4-fill',
-  'coupon-4-line',
-  'coupon-5-fill',
-  'coupon-5-line',
-  'coupon-fill',
-  'coupon-line',
-  'cpu-fill',
-  'cpu-line',
-  'creative-commons-by-fill',
-  'creative-commons-by-line',
-  'creative-commons-fill',
-  'creative-commons-line',
-  'creative-commons-nc-fill',
-  'creative-commons-nc-line',
-  'creative-commons-nd-fill',
-  'creative-commons-nd-line',
-  'creative-commons-sa-fill',
-  'creative-commons-sa-line',
-  'creative-commons-zero-fill',
-  'creative-commons-zero-line',
-  'criminal-fill',
-  'criminal-line',
-  'crop-2-fill',
-  'crop-2-line',
-  'crop-fill',
-  'crop-line',
-  'css3-fill',
-  'css3-line',
-  'cup-fill',
-  'cup-line',
-  'currency-fill',
-  'currency-line',
-  'cursor-fill',
-  'cursor-line',
-  'customer-service-2-fill',
-  'customer-service-2-line',
-  'customer-service-fill',
-  'customer-service-line',
-  'dashboard-2-fill',
-  'dashboard-2-line',
-  'dashboard-3-fill',
-  'dashboard-3-line',
-  'dashboard-fill',
-  'dashboard-line',
-  'database-2-fill',
-  'database-2-line',
-  'database-fill',
-  'database-line',
-  'delete-back-2-fill',
-  'delete-back-2-line',
-  'delete-back-fill',
-  'delete-back-line',
-  'delete-bin-2-fill',
-  'delete-bin-2-line',
-  'delete-bin-3-fill',
-  'delete-bin-3-line',
-  'delete-bin-4-fill',
-  'delete-bin-4-line',
-  'delete-bin-5-fill',
-  'delete-bin-5-line',
-  'delete-bin-6-fill',
-  'delete-bin-6-line',
-  'delete-bin-7-fill',
-  'delete-bin-7-line',
-  'delete-bin-fill',
-  'delete-bin-line',
-  'delete-column',
-  'delete-row',
-  'device-fill',
-  'device-line',
-  'device-recover-fill',
-  'device-recover-line',
-  'dingding-fill',
-  'dingding-line',
-  'direction-fill',
-  'direction-line',
-  'disc-fill',
-  'disc-line',
-  'discord-fill',
-  'discord-line',
-  'discuss-fill',
-  'discuss-line',
-  'dislike-fill',
-  'dislike-line',
-  'disqus-fill',
-  'disqus-line',
-  'divide-fill',
-  'divide-line',
-  'donut-chart-fill',
-  'donut-chart-line',
-  'door-closed-fill',
-  'door-closed-line',
-  'door-fill',
-  'door-line',
-  'door-lock-box-fill',
-  'door-lock-box-line',
-  'door-lock-fill',
-  'door-lock-line',
-  'door-open-fill',
-  'door-open-line',
-  'dossier-fill',
-  'dossier-line',
-  'douban-fill',
-  'douban-line',
-  'double-quotes-l',
-  'double-quotes-r',
-  'download-2-fill',
-  'download-2-line',
-  'download-cloud-2-fill',
-  'download-cloud-2-line',
-  'download-cloud-fill',
-  'download-cloud-line',
-  'download-fill',
-  'download-line',
-  'draft-fill',
-  'draft-line',
-  'drag-drop-fill',
-  'drag-drop-line',
-  'drag-move-2-fill',
-  'drag-move-2-line',
-  'drag-move-fill',
-  'drag-move-line',
-  'dribbble-fill',
-  'dribbble-line',
-  'drive-fill',
-  'drive-line',
-  'drizzle-fill',
-  'drizzle-line',
-  'drop-fill',
-  'drop-line',
-  'dropbox-fill',
-  'dropbox-line',
-  'dual-sim-1-fill',
-  'dual-sim-1-line',
-  'dual-sim-2-fill',
-  'dual-sim-2-line',
-  'dv-fill',
-  'dv-line',
-  'dvd-fill',
-  'dvd-line',
-  'e-bike-2-fill',
-  'e-bike-2-line',
-  'e-bike-fill',
-  'e-bike-line',
-  'earth-fill',
-  'earth-line',
-  'earthquake-fill',
-  'earthquake-line',
-  'edge-fill',
-  'edge-line',
-  'edit-2-fill',
-  'edit-2-line',
-  'edit-box-fill',
-  'edit-box-line',
-  'edit-circle-fill',
-  'edit-circle-line',
-  'edit-fill',
-  'edit-line',
-  'eject-fill',
-  'eject-line',
-  'emotion-2-fill',
-  'emotion-2-line',
-  'emotion-fill',
-  'emotion-happy-fill',
-  'emotion-happy-line',
-  'emotion-laugh-fill',
-  'emotion-laugh-line',
-  'emotion-line',
-  'emotion-normal-fill',
-  'emotion-normal-line',
-  'emotion-sad-fill',
-  'emotion-sad-line',
-  'emotion-unhappy-fill',
-  'emotion-unhappy-line',
-  'empathize-fill',
-  'empathize-line',
-  'emphasis-cn',
-  'emphasis',
-  'english-input',
-  'equalizer-fill',
-  'equalizer-line',
-  'eraser-fill',
-  'eraser-line',
-  'error-warning-fill',
-  'error-warning-line',
-  'evernote-fill',
-  'evernote-line',
-  'exchange-box-fill',
-  'exchange-box-line',
-  'exchange-cny-fill',
-  'exchange-cny-line',
-  'exchange-dollar-fill',
-  'exchange-dollar-line',
-  'exchange-fill',
-  'exchange-funds-fill',
-  'exchange-funds-line',
-  'exchange-line',
-  'external-link-fill',
-  'external-link-line',
-  'eye-2-fill',
-  'eye-2-line',
-  'eye-close-fill',
-  'eye-close-line',
-  'eye-fill',
-  'eye-line',
-  'eye-off-fill',
-  'eye-off-line',
-  'facebook-box-fill',
-  'facebook-box-line',
-  'facebook-circle-fill',
-  'facebook-circle-line',
-  'facebook-fill',
-  'facebook-line',
-  'fahrenheit-fill',
-  'fahrenheit-line',
-  'feedback-fill',
-  'feedback-line',
-  'file-2-fill',
-  'file-2-line',
-  'file-3-fill',
-  'file-3-line',
-  'file-4-fill',
-  'file-4-line',
-  'file-add-fill',
-  'file-add-line',
-  'file-chart-2-fill',
-  'file-chart-2-line',
-  'file-chart-fill',
-  'file-chart-line',
-  'file-cloud-fill',
-  'file-cloud-line',
-  'file-code-fill',
-  'file-code-line',
-  'file-copy-2-fill',
-  'file-copy-2-line',
-  'file-copy-fill',
-  'file-copy-line',
-  'file-damage-fill',
-  'file-damage-line',
-  'file-download-fill',
-  'file-download-line',
-  'file-edit-fill',
-  'file-edit-line',
-  'file-excel-2-fill',
-  'file-excel-2-line',
-  'file-excel-fill',
-  'file-excel-line',
-  'file-fill',
-  'file-forbid-fill',
-  'file-forbid-line',
-  'file-gif-fill',
-  'file-gif-line',
-  'file-history-fill',
-  'file-history-line',
-  'file-hwp-fill',
-  'file-hwp-line',
-  'file-info-fill',
-  'file-info-line',
-  'file-line',
-  'file-list-2-fill',
-  'file-list-2-line',
-  'file-list-3-fill',
-  'file-list-3-line',
-  'file-list-fill',
-  'file-list-line',
-  'file-lock-fill',
-  'file-lock-line',
-  'file-mark-fill',
-  'file-mark-line',
-  'file-music-fill',
-  'file-music-line',
-  'file-paper-2-fill',
-  'file-paper-2-line',
-  'file-paper-fill',
-  'file-paper-line',
-  'file-pdf-fill',
-  'file-pdf-line',
-  'file-ppt-2-fill',
-  'file-ppt-2-line',
-  'file-ppt-fill',
-  'file-ppt-line',
-  'file-reduce-fill',
-  'file-reduce-line',
-  'file-search-fill',
-  'file-search-line',
-  'file-settings-fill',
-  'file-settings-line',
-  'file-shield-2-fill',
-  'file-shield-2-line',
-  'file-shield-fill',
-  'file-shield-line',
-  'file-shred-fill',
-  'file-shred-line',
-  'file-text-fill',
-  'file-text-line',
-  'file-transfer-fill',
-  'file-transfer-line',
-  'file-unknow-fill',
-  'file-unknow-line',
-  'file-upload-fill',
-  'file-upload-line',
-  'file-user-fill',
-  'file-user-line',
-  'file-warning-fill',
-  'file-warning-line',
-  'file-word-2-fill',
-  'file-word-2-line',
-  'file-word-fill',
-  'file-word-line',
-  'file-zip-fill',
-  'file-zip-line',
-  'film-fill',
-  'film-line',
-  'filter-2-fill',
-  'filter-2-line',
-  'filter-3-fill',
-  'filter-3-line',
-  'filter-fill',
-  'filter-line',
-  'filter-off-fill',
-  'filter-off-line',
-  'find-replace-fill',
-  'find-replace-line',
-  'finder-fill',
-  'finder-line',
-  'fingerprint-2-fill',
-  'fingerprint-2-line',
-  'fingerprint-fill',
-  'fingerprint-line',
-  'fire-fill',
-  'fire-line',
-  'firefox-fill',
-  'firefox-line',
-  'first-aid-kit-fill',
-  'first-aid-kit-line',
-  'flag-2-fill',
-  'flag-2-line',
-  'flag-fill',
-  'flag-line',
-  'flashlight-fill',
-  'flashlight-line',
-  'flask-fill',
-  'flask-line',
-  'flight-land-fill',
-  'flight-land-line',
-  'flight-takeoff-fill',
-  'flight-takeoff-line',
-  'flood-fill',
-  'flood-line',
-  'flow-chart',
-  'flutter-fill',
-  'flutter-line',
-  'focus-2-fill',
-  'focus-2-line',
-  'focus-3-fill',
-  'focus-3-line',
-  'focus-fill',
-  'focus-line',
-  'foggy-fill',
-  'foggy-line',
-  'folder-2-fill',
-  'folder-2-line',
-  'folder-3-fill',
-  'folder-3-line',
-  'folder-4-fill',
-  'folder-4-line',
-  'folder-5-fill',
-  'folder-5-line',
-  'folder-add-fill',
-  'folder-add-line',
-  'folder-chart-2-fill',
-  'folder-chart-2-line',
-  'folder-chart-fill',
-  'folder-chart-line',
-  'folder-download-fill',
-  'folder-download-line',
-  'folder-fill',
-  'folder-forbid-fill',
-  'folder-forbid-line',
-  'folder-history-fill',
-  'folder-history-line',
-  'folder-info-fill',
-  'folder-info-line',
-  'folder-keyhole-fill',
-  'folder-keyhole-line',
-  'folder-line',
-  'folder-lock-fill',
-  'folder-lock-line',
-  'folder-music-fill',
-  'folder-music-line',
-  'folder-open-fill',
-  'folder-open-line',
-  'folder-received-fill',
-  'folder-received-line',
-  'folder-reduce-fill',
-  'folder-reduce-line',
-  'folder-settings-fill',
-  'folder-settings-line',
-  'folder-shared-fill',
-  'folder-shared-line',
-  'folder-shield-2-fill',
-  'folder-shield-2-line',
-  'folder-shield-fill',
-  'folder-shield-line',
-  'folder-transfer-fill',
-  'folder-transfer-line',
-  'folder-unknow-fill',
-  'folder-unknow-line',
-  'folder-upload-fill',
-  'folder-upload-line',
-  'folder-user-fill',
-  'folder-user-line',
-  'folder-warning-fill',
-  'folder-warning-line',
-  'folder-zip-fill',
-  'folder-zip-line',
-  'folders-fill',
-  'folders-line',
-  'font-color',
-  'font-size-2',
-  'font-size',
-  'football-fill',
-  'football-line',
-  'footprint-fill',
-  'footprint-line',
-  'forbid-2-fill',
-  'forbid-2-line',
-  'forbid-fill',
-  'forbid-line',
-  'format-clear',
-  'fridge-fill',
-  'fridge-line',
-  'fullscreen-exit-fill',
-  'fullscreen-exit-line',
-  'fullscreen-fill',
-  'fullscreen-line',
-  'function-fill',
-  'function-line',
-  'functions',
-  'funds-box-fill',
-  'funds-box-line',
-  'funds-fill',
-  'funds-line',
-  'gallery-fill',
-  'gallery-line',
-  'gallery-upload-fill',
-  'gallery-upload-line',
-  'game-fill',
-  'game-line',
-  'gamepad-fill',
-  'gamepad-line',
-  'gas-station-fill',
-  'gas-station-line',
-  'gatsby-fill',
-  'gatsby-line',
-  'genderless-fill',
-  'genderless-line',
-  'ghost-2-fill',
-  'ghost-2-line',
-  'ghost-fill',
-  'ghost-line',
-  'ghost-smile-fill',
-  'ghost-smile-line',
-  'gift-2-fill',
-  'gift-2-line',
-  'gift-fill',
-  'gift-line',
-  'git-branch-fill',
-  'git-branch-line',
-  'git-commit-fill',
-  'git-commit-line',
-  'git-merge-fill',
-  'git-merge-line',
-  'git-pull-request-fill',
-  'git-pull-request-line',
-  'git-repository-commits-fill',
-  'git-repository-commits-line',
-  'git-repository-fill',
-  'git-repository-line',
-  'git-repository-private-fill',
-  'git-repository-private-line',
-  'github-fill',
-  'github-line',
-  'gitlab-fill',
-  'gitlab-line',
-  'global-fill',
-  'global-line',
-  'globe-fill',
-  'globe-line',
-  'goblet-fill',
-  'goblet-line',
-  'google-fill',
-  'google-line',
-  'google-play-fill',
-  'google-play-line',
-  'government-fill',
-  'government-line',
-  'gps-fill',
-  'gps-line',
-  'gradienter-fill',
-  'gradienter-line',
-  'grid-fill',
-  'grid-line',
-  'group-2-fill',
-  'group-2-line',
-  'group-fill',
-  'group-line',
-  'guide-fill',
-  'guide-line',
-  'h-1',
-  'h-2',
-  'h-3',
-  'h-4',
-  'h-5',
-  'h-6',
-  'hail-fill',
-  'hail-line',
-  'hammer-fill',
-  'hammer-line',
-  'hand-coin-fill',
-  'hand-coin-line',
-  'hand-heart-fill',
-  'hand-heart-line',
-  'hand-sanitizer-fill',
-  'hand-sanitizer-line',
-  'handbag-fill',
-  'handbag-line',
-  'hard-drive-2-fill',
-  'hard-drive-2-line',
-  'hard-drive-fill',
-  'hard-drive-line',
-  'hashtag',
-  'haze-2-fill',
-  'haze-2-line',
-  'haze-fill',
-  'haze-line',
-  'hd-fill',
-  'hd-line',
-  'heading',
-  'headphone-fill',
-  'headphone-line',
-  'health-book-fill',
-  'health-book-line',
-  'heart-2-fill',
-  'heart-2-line',
-  'heart-3-fill',
-  'heart-3-line',
-  'heart-add-fill',
-  'heart-add-line',
-  'heart-fill',
-  'heart-line',
-  'heart-pulse-fill',
-  'heart-pulse-line',
-  'hearts-fill',
-  'hearts-line',
-  'heavy-showers-fill',
-  'heavy-showers-line',
-  'history-fill',
-  'history-line',
-  'home-2-fill',
-  'home-2-line',
-  'home-3-fill',
-  'home-3-line',
-  'home-4-fill',
-  'home-4-line',
-  'home-5-fill',
-  'home-5-line',
-  'home-6-fill',
-  'home-6-line',
-  'home-7-fill',
-  'home-7-line',
-  'home-8-fill',
-  'home-8-line',
-  'home-fill',
-  'home-gear-fill',
-  'home-gear-line',
-  'home-heart-fill',
-  'home-heart-line',
-  'home-line',
-  'home-smile-2-fill',
-  'home-smile-2-line',
-  'home-smile-fill',
-  'home-smile-line',
-  'home-wifi-fill',
-  'home-wifi-line',
-  'honor-of-kings-fill',
-  'honor-of-kings-line',
-  'honour-fill',
-  'honour-line',
-  'hospital-fill',
-  'hospital-line',
-  'hotel-bed-fill',
-  'hotel-bed-line',
-  'hotel-fill',
-  'hotel-line',
-  'hotspot-fill',
-  'hotspot-line',
-  'hq-fill',
-  'hq-line',
-  'html5-fill',
-  'html5-line',
-  'ie-fill',
-  'ie-line',
-  'image-2-fill',
-  'image-2-line',
-  'image-add-fill',
-  'image-add-line',
-  'image-edit-fill',
-  'image-edit-line',
-  'image-fill',
-  'image-line',
-  'inbox-archive-fill',
-  'inbox-archive-line',
-  'inbox-fill',
-  'inbox-line',
-  'inbox-unarchive-fill',
-  'inbox-unarchive-line',
-  'increase-decrease-fill',
-  'increase-decrease-line',
-  'indent-decrease',
-  'indent-increase',
-  'indeterminate-circle-fill',
-  'indeterminate-circle-line',
-  'information-fill',
-  'information-line',
-  'infrared-thermometer-fill',
-  'infrared-thermometer-line',
-  'ink-bottle-fill',
-  'ink-bottle-line',
-  'input-cursor-move',
-  'input-method-fill',
-  'input-method-line',
-  'insert-column-left',
-  'insert-column-right',
-  'insert-row-bottom',
-  'insert-row-top',
-  'instagram-fill',
-  'instagram-line',
-  'install-fill',
-  'install-line',
-  'invision-fill',
-  'invision-line',
-  'italic',
-  'kakao-talk-fill',
-  'kakao-talk-line',
-  'key-2-fill',
-  'key-2-line',
-  'key-fill',
-  'key-line',
-  'keyboard-box-fill',
-  'keyboard-box-line',
-  'keyboard-fill',
-  'keyboard-line',
-  'keynote-fill',
-  'keynote-line',
-  'knife-blood-fill',
-  'knife-blood-line',
-  'knife-fill',
-  'knife-line',
-  'landscape-fill',
-  'landscape-line',
-  'layout-2-fill',
-  'layout-2-line',
-  'layout-3-fill',
-  'layout-3-line',
-  'layout-4-fill',
-  'layout-4-line',
-  'layout-5-fill',
-  'layout-5-line',
-  'layout-6-fill',
-  'layout-6-line',
-  'layout-bottom-2-fill',
-  'layout-bottom-2-line',
-  'layout-bottom-fill',
-  'layout-bottom-line',
-  'layout-column-fill',
-  'layout-column-line',
-  'layout-fill',
-  'layout-grid-fill',
-  'layout-grid-line',
-  'layout-left-2-fill',
-  'layout-left-2-line',
-  'layout-left-fill',
-  'layout-left-line',
-  'layout-line',
-  'layout-masonry-fill',
-  'layout-masonry-line',
-  'layout-right-2-fill',
-  'layout-right-2-line',
-  'layout-right-fill',
-  'layout-right-line',
-  'layout-row-fill',
-  'layout-row-line',
-  'layout-top-2-fill',
-  'layout-top-2-line',
-  'layout-top-fill',
-  'layout-top-line',
-  'leaf-fill',
-  'leaf-line',
-  'lifebuoy-fill',
-  'lifebuoy-line',
-  'lightbulb-fill',
-  'lightbulb-flash-fill',
-  'lightbulb-flash-line',
-  'lightbulb-line',
-  'line-chart-fill',
-  'line-chart-line',
-  'line-fill',
-  'line-height',
-  'line-line',
-  'link-m',
-  'link-unlink-m',
-  'link-unlink',
-  'link',
-  'linkedin-box-fill',
-  'linkedin-box-line',
-  'linkedin-fill',
-  'linkedin-line',
-  'links-fill',
-  'links-line',
-  'list-check-2',
-  'list-check',
-  'list-ordered',
-  'list-settings-fill',
-  'list-settings-line',
-  'list-unordered',
-  'live-fill',
-  'live-line',
-  'loader-2-fill',
-  'loader-2-line',
-  'loader-3-fill',
-  'loader-3-line',
-  'loader-4-fill',
-  'loader-4-line',
-  'loader-5-fill',
-  'loader-5-line',
-  'loader-fill',
-  'loader-line',
-  'lock-2-fill',
-  'lock-2-line',
-  'lock-fill',
-  'lock-line',
-  'lock-password-fill',
-  'lock-password-line',
-  'lock-unlock-fill',
-  'lock-unlock-line',
-  'login-box-fill',
-  'login-box-line',
-  'login-circle-fill',
-  'login-circle-line',
-  'logout-box-fill',
-  'logout-box-line',
-  'logout-box-r-fill',
-  'logout-box-r-line',
-  'logout-circle-fill',
-  'logout-circle-line',
-  'logout-circle-r-fill',
-  'logout-circle-r-line',
-  'luggage-cart-fill',
-  'luggage-cart-line',
-  'luggage-deposit-fill',
-  'luggage-deposit-line',
-  'lungs-fill',
-  'lungs-line',
-  'mac-fill',
-  'mac-line',
-  'macbook-fill',
-  'macbook-line',
-  'magic-fill',
-  'magic-line',
-  'mail-add-fill',
-  'mail-add-line',
-  'mail-check-fill',
-  'mail-check-line',
-  'mail-close-fill',
-  'mail-close-line',
-  'mail-download-fill',
-  'mail-download-line',
-  'mail-fill',
-  'mail-forbid-fill',
-  'mail-forbid-line',
-  'mail-line',
-  'mail-lock-fill',
-  'mail-lock-line',
-  'mail-open-fill',
-  'mail-open-line',
-  'mail-send-fill',
-  'mail-send-line',
-  'mail-settings-fill',
-  'mail-settings-line',
-  'mail-star-fill',
-  'mail-star-line',
-  'mail-unread-fill',
-  'mail-unread-line',
-  'mail-volume-fill',
-  'mail-volume-line',
-  'map-2-fill',
-  'map-2-line',
-  'map-fill',
-  'map-line',
-  'map-pin-2-fill',
-  'map-pin-2-line',
-  'map-pin-3-fill',
-  'map-pin-3-line',
-  'map-pin-4-fill',
-  'map-pin-4-line',
-  'map-pin-5-fill',
-  'map-pin-5-line',
-  'map-pin-add-fill',
-  'map-pin-add-line',
-  'map-pin-fill',
-  'map-pin-line',
-  'map-pin-range-fill',
-  'map-pin-range-line',
-  'map-pin-time-fill',
-  'map-pin-time-line',
-  'map-pin-user-fill',
-  'map-pin-user-line',
-  'mark-pen-fill',
-  'mark-pen-line',
-  'markdown-fill',
-  'markdown-line',
-  'markup-fill',
-  'markup-line',
-  'mastercard-fill',
-  'mastercard-line',
-  'mastodon-fill',
-  'mastodon-line',
-  'medal-2-fill',
-  'medal-2-line',
-  'medal-fill',
-  'medal-line',
-  'medicine-bottle-fill',
-  'medicine-bottle-line',
-  'medium-fill',
-  'medium-line',
-  'men-fill',
-  'men-line',
-  'mental-health-fill',
-  'mental-health-line',
-  'menu-2-fill',
-  'menu-2-line',
-  'menu-3-fill',
-  'menu-3-line',
-  'menu-4-fill',
-  'menu-4-line',
-  'menu-5-fill',
-  'menu-5-line',
-  'menu-add-fill',
-  'menu-add-line',
-  'menu-fill',
-  'menu-fold-fill',
-  'menu-fold-line',
-  'menu-line',
-  'menu-unfold-fill',
-  'menu-unfold-line',
-  'merge-cells-horizontal',
-  'merge-cells-vertical',
-  'message-2-fill',
-  'message-2-line',
-  'message-3-fill',
-  'message-3-line',
-  'message-fill',
-  'message-line',
-  'messenger-fill',
-  'messenger-line',
-  'meteor-fill',
-  'meteor-line',
-  'mic-2-fill',
-  'mic-2-line',
-  'mic-fill',
-  'mic-line',
-  'mic-off-fill',
-  'mic-off-line',
-  'mickey-fill',
-  'mickey-line',
-  'microscope-fill',
-  'microscope-line',
-  'microsoft-fill',
-  'microsoft-line',
-  'mind-map',
-  'mini-program-fill',
-  'mini-program-line',
-  'mist-fill',
-  'mist-line',
-  'money-cny-box-fill',
-  'money-cny-box-line',
-  'money-cny-circle-fill',
-  'money-cny-circle-line',
-  'money-dollar-box-fill',
-  'money-dollar-box-line',
-  'money-dollar-circle-fill',
-  'money-dollar-circle-line',
-  'money-euro-box-fill',
-  'money-euro-box-line',
-  'money-euro-circle-fill',
-  'money-euro-circle-line',
-  'money-pound-box-fill',
-  'money-pound-box-line',
-  'money-pound-circle-fill',
-  'money-pound-circle-line',
-  'moon-clear-fill',
-  'moon-clear-line',
-  'moon-cloudy-fill',
-  'moon-cloudy-line',
-  'moon-fill',
-  'moon-foggy-fill',
-  'moon-foggy-line',
-  'moon-line',
-  'more-2-fill',
-  'more-2-line',
-  'more-fill',
-  'more-line',
-  'motorbike-fill',
-  'motorbike-line',
-  'mouse-fill',
-  'mouse-line',
-  'movie-2-fill',
-  'movie-2-line',
-  'movie-fill',
-  'movie-line',
-  'music-2-fill',
-  'music-2-line',
-  'music-fill',
-  'music-line',
-  'mv-fill',
-  'mv-line',
-  'navigation-fill',
-  'navigation-line',
-  'netease-cloud-music-fill',
-  'netease-cloud-music-line',
-  'netflix-fill',
-  'netflix-line',
-  'newspaper-fill',
-  'newspaper-line',
-  'node-tree',
-  'notification-2-fill',
-  'notification-2-line',
-  'notification-3-fill',
-  'notification-3-line',
-  'notification-4-fill',
-  'notification-4-line',
-  'notification-badge-fill',
-  'notification-badge-line',
-  'notification-fill',
-  'notification-line',
-  'notification-off-fill',
-  'notification-off-line',
-  'npmjs-fill',
-  'npmjs-line',
-  'number-0',
-  'number-1',
-  'number-2',
-  'number-3',
-  'number-4',
-  'number-5',
-  'number-6',
-  'number-7',
-  'number-8',
-  'number-9',
-  'numbers-fill',
-  'numbers-line',
-  'nurse-fill',
-  'nurse-line',
-  'oil-fill',
-  'oil-line',
-  'omega',
-  'open-arm-fill',
-  'open-arm-line',
-  'open-source-fill',
-  'open-source-line',
-  'opera-fill',
-  'opera-line',
-  'order-play-fill',
-  'order-play-line',
-  'organization-chart',
-  'outlet-2-fill',
-  'outlet-2-line',
-  'outlet-fill',
-  'outlet-line',
-  'page-separator',
-  'pages-fill',
-  'pages-line',
-  'paint-brush-fill',
-  'paint-brush-line',
-  'paint-fill',
-  'paint-line',
-  'palette-fill',
-  'palette-line',
-  'pantone-fill',
-  'pantone-line',
-  'paragraph',
-  'parent-fill',
-  'parent-line',
-  'parentheses-fill',
-  'parentheses-line',
-  'parking-box-fill',
-  'parking-box-line',
-  'parking-fill',
-  'parking-line',
-  'passport-fill',
-  'passport-line',
-  'patreon-fill',
-  'patreon-line',
-  'pause-circle-fill',
-  'pause-circle-line',
-  'pause-fill',
-  'pause-line',
-  'pause-mini-fill',
-  'pause-mini-line',
-  'paypal-fill',
-  'paypal-line',
-  'pen-nib-fill',
-  'pen-nib-line',
-  'pencil-fill',
-  'pencil-line',
-  'pencil-ruler-2-fill',
-  'pencil-ruler-2-line',
-  'pencil-ruler-fill',
-  'pencil-ruler-line',
-  'percent-fill',
-  'percent-line',
-  'phone-camera-fill',
-  'phone-camera-line',
-  'phone-fill',
-  'phone-find-fill',
-  'phone-find-line',
-  'phone-line',
-  'phone-lock-fill',
-  'phone-lock-line',
-  'picture-in-picture-2-fill',
-  'picture-in-picture-2-line',
-  'picture-in-picture-exit-fill',
-  'picture-in-picture-exit-line',
-  'picture-in-picture-fill',
-  'picture-in-picture-line',
-  'pie-chart-2-fill',
-  'pie-chart-2-line',
-  'pie-chart-box-fill',
-  'pie-chart-box-line',
-  'pie-chart-fill',
-  'pie-chart-line',
-  'pin-distance-fill',
-  'pin-distance-line',
-  'ping-pong-fill',
-  'ping-pong-line',
-  'pinterest-fill',
-  'pinterest-line',
-  'pinyin-input',
-  'pixelfed-fill',
-  'pixelfed-line',
-  'plane-fill',
-  'plane-line',
-  'plant-fill',
-  'plant-line',
-  'play-circle-fill',
-  'play-circle-line',
-  'play-fill',
-  'play-line',
-  'play-list-2-fill',
-  'play-list-2-line',
-  'play-list-add-fill',
-  'play-list-add-line',
-  'play-list-fill',
-  'play-list-line',
-  'play-mini-fill',
-  'play-mini-line',
-  'playstation-fill',
-  'playstation-line',
-  'plug-2-fill',
-  'plug-2-line',
-  'plug-fill',
-  'plug-line',
-  'polaroid-2-fill',
-  'polaroid-2-line',
-  'polaroid-fill',
-  'polaroid-line',
-  'police-car-fill',
-  'police-car-line',
-  'price-tag-2-fill',
-  'price-tag-2-line',
-  'price-tag-3-fill',
-  'price-tag-3-line',
-  'price-tag-fill',
-  'price-tag-line',
-  'printer-cloud-fill',
-  'printer-cloud-line',
-  'printer-fill',
-  'printer-line',
-  'product-hunt-fill',
-  'product-hunt-line',
-  'profile-fill',
-  'profile-line',
-  'projector-2-fill',
-  'projector-2-line',
-  'projector-fill',
-  'projector-line',
-  'psychotherapy-fill',
-  'psychotherapy-line',
-  'pulse-fill',
-  'pulse-line',
-  'pushpin-2-fill',
-  'pushpin-2-line',
-  'pushpin-fill',
-  'pushpin-line',
-  'qq-fill',
-  'qq-line',
-  'qr-code-fill',
-  'qr-code-line',
-  'qr-scan-2-fill',
-  'qr-scan-2-line',
-  'qr-scan-fill',
-  'qr-scan-line',
-  'question-answer-fill',
-  'question-answer-line',
-  'question-fill',
-  'question-line',
-  'question-mark',
-  'questionnaire-fill',
-  'questionnaire-line',
-  'quill-pen-fill',
-  'quill-pen-line',
-  'radar-fill',
-  'radar-line',
-  'radio-2-fill',
-  'radio-2-line',
-  'radio-button-fill',
-  'radio-button-line',
-  'radio-fill',
-  'radio-line',
-  'rainbow-fill',
-  'rainbow-line',
-  'rainy-fill',
-  'rainy-line',
-  'reactjs-fill',
-  'reactjs-line',
-  'record-circle-fill',
-  'record-circle-line',
-  'record-mail-fill',
-  'record-mail-line',
-  'recycle-fill',
-  'recycle-line',
-  'red-packet-fill',
-  'red-packet-line',
-  'reddit-fill',
-  'reddit-line',
-  'refresh-fill',
-  'refresh-line',
-  'refund-2-fill',
-  'refund-2-line',
-  'refund-fill',
-  'refund-line',
-  'registered-fill',
-  'registered-line',
-  'remixicon-fill',
-  'remixicon-line',
-  'remote-control-2-fill',
-  'remote-control-2-line',
-  'remote-control-fill',
-  'remote-control-line',
-  'repeat-2-fill',
-  'repeat-2-line',
-  'repeat-fill',
-  'repeat-line',
-  'repeat-one-fill',
-  'repeat-one-line',
-  'reply-all-fill',
-  'reply-all-line',
-  'reply-fill',
-  'reply-line',
-  'reserved-fill',
-  'reserved-line',
-  'rest-time-fill',
-  'rest-time-line',
-  'restart-fill',
-  'restart-line',
-  'restaurant-2-fill',
-  'restaurant-2-line',
-  'restaurant-fill',
-  'restaurant-line',
-  'rewind-fill',
-  'rewind-line',
-  'rewind-mini-fill',
-  'rewind-mini-line',
-  'rhythm-fill',
-  'rhythm-line',
-  'riding-fill',
-  'riding-line',
-  'road-map-fill',
-  'road-map-line',
-  'roadster-fill',
-  'roadster-line',
-  'robot-fill',
-  'robot-line',
-  'rocket-2-fill',
-  'rocket-2-line',
-  'rocket-fill',
-  'rocket-line',
-  'rotate-lock-fill',
-  'rotate-lock-line',
-  'rounded-corner',
-  'route-fill',
-  'route-line',
-  'router-fill',
-  'router-line',
-  'rss-fill',
-  'rss-line',
-  'ruler-2-fill',
-  'ruler-2-line',
-  'ruler-fill',
-  'ruler-line',
-  'run-fill',
-  'run-line',
-  'safari-fill',
-  'safari-line',
-  'safe-2-fill',
-  'safe-2-line',
-  'safe-fill',
-  'safe-line',
-  'sailboat-fill',
-  'sailboat-line',
-  'save-2-fill',
-  'save-2-line',
-  'save-3-fill',
-  'save-3-line',
-  'save-fill',
-  'save-line',
-  'scales-2-fill',
-  'scales-2-line',
-  'scales-3-fill',
-  'scales-3-line',
-  'scales-fill',
-  'scales-line',
-  'scan-2-fill',
-  'scan-2-line',
-  'scan-fill',
-  'scan-line',
-  'scissors-2-fill',
-  'scissors-2-line',
-  'scissors-cut-fill',
-  'scissors-cut-line',
-  'scissors-fill',
-  'scissors-line',
-  'screenshot-2-fill',
-  'screenshot-2-line',
-  'screenshot-fill',
-  'screenshot-line',
-  'sd-card-fill',
-  'sd-card-line',
-  'sd-card-mini-fill',
-  'sd-card-mini-line',
-  'search-2-fill',
-  'search-2-line',
-  'search-eye-fill',
-  'search-eye-line',
-  'search-fill',
-  'search-line',
-  'secure-payment-fill',
-  'secure-payment-line',
-  'seedling-fill',
-  'seedling-line',
-  'send-backward',
-  'send-plane-2-fill',
-  'send-plane-2-line',
-  'send-plane-fill',
-  'send-plane-line',
-  'send-to-back',
-  'sensor-fill',
-  'sensor-line',
-  'separator',
-  'server-fill',
-  'server-line',
-  'service-fill',
-  'service-line',
-  'settings-2-fill',
-  'settings-2-line',
-  'settings-3-fill',
-  'settings-3-line',
-  'settings-4-fill',
-  'settings-4-line',
-  'settings-5-fill',
-  'settings-5-line',
-  'settings-6-fill',
-  'settings-6-line',
-  'settings-fill',
-  'settings-line',
-  'shape-2-fill',
-  'shape-2-line',
-  'shape-fill',
-  'shape-line',
-  'share-box-fill',
-  'share-box-line',
-  'share-circle-fill',
-  'share-circle-line',
-  'share-fill',
-  'share-forward-2-fill',
-  'share-forward-2-line',
-  'share-forward-box-fill',
-  'share-forward-box-line',
-  'share-forward-fill',
-  'share-forward-line',
-  'share-line',
-  'shield-check-fill',
-  'shield-check-line',
-  'shield-cross-fill',
-  'shield-cross-line',
-  'shield-fill',
-  'shield-flash-fill',
-  'shield-flash-line',
-  'shield-keyhole-fill',
-  'shield-keyhole-line',
-  'shield-line',
-  'shield-star-fill',
-  'shield-star-line',
-  'shield-user-fill',
-  'shield-user-line',
-  'ship-2-fill',
-  'ship-2-line',
-  'ship-fill',
-  'ship-line',
-  'shirt-fill',
-  'shirt-line',
-  'shopping-bag-2-fill',
-  'shopping-bag-2-line',
-  'shopping-bag-3-fill',
-  'shopping-bag-3-line',
-  'shopping-bag-fill',
-  'shopping-bag-line',
-  'shopping-basket-2-fill',
-  'shopping-basket-2-line',
-  'shopping-basket-fill',
-  'shopping-basket-line',
-  'shopping-cart-2-fill',
-  'shopping-cart-2-line',
-  'shopping-cart-fill',
-  'shopping-cart-line',
-  'showers-fill',
-  'showers-line',
-  'shuffle-fill',
-  'shuffle-line',
-  'shut-down-fill',
-  'shut-down-line',
-  'side-bar-fill',
-  'side-bar-line',
-  'signal-tower-fill',
-  'signal-tower-line',
-  'signal-wifi-1-fill',
-  'signal-wifi-1-line',
-  'signal-wifi-2-fill',
-  'signal-wifi-2-line',
-  'signal-wifi-3-fill',
-  'signal-wifi-3-line',
-  'signal-wifi-error-fill',
-  'signal-wifi-error-line',
-  'signal-wifi-fill',
-  'signal-wifi-line',
-  'signal-wifi-off-fill',
-  'signal-wifi-off-line',
-  'sim-card-2-fill',
-  'sim-card-2-line',
-  'sim-card-fill',
-  'sim-card-line',
-  'single-quotes-l',
-  'single-quotes-r',
-  'sip-fill',
-  'sip-line',
-  'skip-back-fill',
-  'skip-back-line',
-  'skip-back-mini-fill',
-  'skip-back-mini-line',
-  'skip-forward-fill',
-  'skip-forward-line',
-  'skip-forward-mini-fill',
-  'skip-forward-mini-line',
-  'skull-2-fill',
-  'skull-2-line',
-  'skull-fill',
-  'skull-line',
-  'skype-fill',
-  'skype-line',
-  'slack-fill',
-  'slack-line',
-  'slice-fill',
-  'slice-line',
-  'slideshow-2-fill',
-  'slideshow-2-line',
-  'slideshow-3-fill',
-  'slideshow-3-line',
-  'slideshow-4-fill',
-  'slideshow-4-line',
-  'slideshow-fill',
-  'slideshow-line',
-  'smartphone-fill',
-  'smartphone-line',
-  'snapchat-fill',
-  'snapchat-line',
-  'snowy-fill',
-  'snowy-line',
-  'sort-asc',
-  'sort-desc',
-  'sound-module-fill',
-  'sound-module-line',
-  'soundcloud-fill',
-  'soundcloud-line',
-  'space-ship-fill',
-  'space-ship-line',
-  'space',
-  'spam-2-fill',
-  'spam-2-line',
-  'spam-3-fill',
-  'spam-3-line',
-  'spam-fill',
-  'spam-line',
-  'speaker-2-fill',
-  'speaker-2-line',
-  'speaker-3-fill',
-  'speaker-3-line',
-  'speaker-fill',
-  'speaker-line',
-  'spectrum-fill',
-  'spectrum-line',
-  'speed-fill',
-  'speed-line',
-  'speed-mini-fill',
-  'speed-mini-line',
-  'split-cells-horizontal',
-  'split-cells-vertical',
-  'spotify-fill',
-  'spotify-line',
-  'spy-fill',
-  'spy-line',
-  'stack-fill',
-  'stack-line',
-  'stack-overflow-fill',
-  'stack-overflow-line',
-  'stackshare-fill',
-  'stackshare-line',
-  'star-fill',
-  'star-half-fill',
-  'star-half-line',
-  'star-half-s-fill',
-  'star-half-s-line',
-  'star-line',
-  'star-s-fill',
-  'star-s-line',
-  'star-smile-fill',
-  'star-smile-line',
-  'steam-fill',
-  'steam-line',
-  'steering-2-fill',
-  'steering-2-line',
-  'steering-fill',
-  'steering-line',
-  'stethoscope-fill',
-  'stethoscope-line',
-  'sticky-note-2-fill',
-  'sticky-note-2-line',
-  'sticky-note-fill',
-  'sticky-note-line',
-  'stock-fill',
-  'stock-line',
-  'stop-circle-fill',
-  'stop-circle-line',
-  'stop-fill',
-  'stop-line',
-  'stop-mini-fill',
-  'stop-mini-line',
-  'store-2-fill',
-  'store-2-line',
-  'store-3-fill',
-  'store-3-line',
-  'store-fill',
-  'store-line',
-  'strikethrough-2',
-  'strikethrough',
-  'subscript-2',
-  'subscript',
-  'subtract-fill',
-  'subtract-line',
-  'subway-fill',
-  'subway-line',
-  'subway-wifi-fill',
-  'subway-wifi-line',
-  'suitcase-2-fill',
-  'suitcase-2-line',
-  'suitcase-3-fill',
-  'suitcase-3-line',
-  'suitcase-fill',
-  'suitcase-line',
-  'sun-cloudy-fill',
-  'sun-cloudy-line',
-  'sun-fill',
-  'sun-foggy-fill',
-  'sun-foggy-line',
-  'sun-line',
-  'superscript-2',
-  'superscript',
-  'surgical-mask-fill',
-  'surgical-mask-line',
-  'surround-sound-fill',
-  'surround-sound-line',
-  'survey-fill',
-  'survey-line',
-  'swap-box-fill',
-  'swap-box-line',
-  'swap-fill',
-  'swap-line',
-  'switch-fill',
-  'switch-line',
-  'sword-fill',
-  'sword-line',
-  'syringe-fill',
-  'syringe-line',
-  't-box-fill',
-  't-box-line',
-  't-shirt-2-fill',
-  't-shirt-2-line',
-  't-shirt-air-fill',
-  't-shirt-air-line',
-  't-shirt-fill',
-  't-shirt-line',
-  'table-2',
-  'table-alt-fill',
-  'table-alt-line',
-  'table-fill',
-  'table-line',
-  'tablet-fill',
-  'tablet-line',
-  'takeaway-fill',
-  'takeaway-line',
-  'taobao-fill',
-  'taobao-line',
-  'tape-fill',
-  'tape-line',
-  'task-fill',
-  'task-line',
-  'taxi-fill',
-  'taxi-line',
-  'taxi-wifi-fill',
-  'taxi-wifi-line',
-  'team-fill',
-  'team-line',
-  'telegram-fill',
-  'telegram-line',
-  'temp-cold-fill',
-  'temp-cold-line',
-  'temp-hot-fill',
-  'temp-hot-line',
-  'terminal-box-fill',
-  'terminal-box-line',
-  'terminal-fill',
-  'terminal-line',
-  'terminal-window-fill',
-  'terminal-window-line',
-  'test-tube-fill',
-  'test-tube-line',
-  'text-direction-l',
-  'text-direction-r',
-  'text-spacing',
-  'text-wrap',
-  'text',
-  'thermometer-fill',
-  'thermometer-line',
-  'thumb-down-fill',
-  'thumb-down-line',
-  'thumb-up-fill',
-  'thumb-up-line',
-  'thunderstorms-fill',
-  'thunderstorms-line',
-  'ticket-2-fill',
-  'ticket-2-line',
-  'ticket-fill',
-  'ticket-line',
-  'time-fill',
-  'time-line',
-  'timer-2-fill',
-  'timer-2-line',
-  'timer-fill',
-  'timer-flash-fill',
-  'timer-flash-line',
-  'timer-line',
-  'todo-fill',
-  'todo-line',
-  'toggle-fill',
-  'toggle-line',
-  'tools-fill',
-  'tools-line',
-  'tornado-fill',
-  'tornado-line',
-  'trademark-fill',
-  'trademark-line',
-  'traffic-light-fill',
-  'traffic-light-line',
-  'train-fill',
-  'train-line',
-  'train-wifi-fill',
-  'train-wifi-line',
-  'translate-2',
-  'translate',
-  'travesti-fill',
-  'travesti-line',
-  'treasure-map-fill',
-  'treasure-map-line',
-  'trello-fill',
-  'trello-line',
-  'trophy-fill',
-  'trophy-line',
-  'truck-fill',
-  'truck-line',
-  'tumblr-fill',
-  'tumblr-line',
-  'tv-2-fill',
-  'tv-2-line',
-  'tv-fill',
-  'tv-line',
-  'twitch-fill',
-  'twitch-line',
-  'twitter-fill',
-  'twitter-line',
-  'typhoon-fill',
-  'typhoon-line',
-  'u-disk-fill',
-  'u-disk-line',
-  'ubuntu-fill',
-  'ubuntu-line',
-  'umbrella-fill',
-  'umbrella-line',
-  'underline',
-  'uninstall-fill',
-  'uninstall-line',
-  'unsplash-fill',
-  'unsplash-line',
-  'upload-2-fill',
-  'upload-2-line',
-  'upload-cloud-2-fill',
-  'upload-cloud-2-line',
-  'upload-cloud-fill',
-  'upload-cloud-line',
-  'upload-fill',
-  'upload-line',
-  'usb-fill',
-  'usb-line',
-  'user-2-fill',
-  'user-2-line',
-  'user-3-fill',
-  'user-3-line',
-  'user-4-fill',
-  'user-4-line',
-  'user-5-fill',
-  'user-5-line',
-  'user-6-fill',
-  'user-6-line',
-  'user-add-fill',
-  'user-add-line',
-  'user-fill',
-  'user-follow-fill',
-  'user-follow-line',
-  'user-heart-fill',
-  'user-heart-line',
-  'user-line',
-  'user-location-fill',
-  'user-location-line',
-  'user-received-2-fill',
-  'user-received-2-line',
-  'user-received-fill',
-  'user-received-line',
-  'user-search-fill',
-  'user-search-line',
-  'user-settings-fill',
-  'user-settings-line',
-  'user-shared-2-fill',
-  'user-shared-2-line',
-  'user-shared-fill',
-  'user-shared-line',
-  'user-smile-fill',
-  'user-smile-line',
-  'user-star-fill',
-  'user-star-line',
-  'user-unfollow-fill',
-  'user-unfollow-line',
-  'user-voice-fill',
-  'user-voice-line',
-  'video-add-fill',
-  'video-add-line',
-  'video-chat-fill',
-  'video-chat-line',
-  'video-download-fill',
-  'video-download-line',
-  'video-fill',
-  'video-line',
-  'video-upload-fill',
-  'video-upload-line',
-  'vidicon-2-fill',
-  'vidicon-2-line',
-  'vidicon-fill',
-  'vidicon-line',
-  'vimeo-fill',
-  'vimeo-line',
-  'vip-crown-2-fill',
-  'vip-crown-2-line',
-  'vip-crown-fill',
-  'vip-crown-line',
-  'vip-diamond-fill',
-  'vip-diamond-line',
-  'vip-fill',
-  'vip-line',
-  'virus-fill',
-  'virus-line',
-  'visa-fill',
-  'visa-line',
-  'voice-recognition-fill',
-  'voice-recognition-line',
-  'voiceprint-fill',
-  'voiceprint-line',
-  'volume-down-fill',
-  'volume-down-line',
-  'volume-mute-fill',
-  'volume-mute-line',
-  'volume-off-vibrate-fill',
-  'volume-off-vibrate-line',
-  'volume-up-fill',
-  'volume-up-line',
-  'volume-vibrate-fill',
-  'volume-vibrate-line',
-  'vuejs-fill',
-  'vuejs-line',
-  'walk-fill',
-  'walk-line',
-  'wallet-2-fill',
-  'wallet-2-line',
-  'wallet-3-fill',
-  'wallet-3-line',
-  'wallet-fill',
-  'wallet-line',
-  'water-flash-fill',
-  'water-flash-line',
-  'webcam-fill',
-  'webcam-line',
-  'wechat-2-fill',
-  'wechat-2-line',
-  'wechat-fill',
-  'wechat-line',
-  'wechat-pay-fill',
-  'wechat-pay-line',
-  'weibo-fill',
-  'weibo-line',
-  'whatsapp-fill',
-  'whatsapp-line',
-  'wheelchair-fill',
-  'wheelchair-line',
-  'wifi-fill',
-  'wifi-line',
-  'wifi-off-fill',
-  'wifi-off-line',
-  'window-2-fill',
-  'window-2-line',
-  'window-fill',
-  'window-line',
-  'windows-fill',
-  'windows-line',
-  'windy-fill',
-  'windy-line',
-  'wireless-charging-fill',
-  'wireless-charging-line',
-  'women-fill',
-  'women-line',
-  'wubi-input',
-  'xbox-fill',
-  'xbox-line',
-  'xing-fill',
-  'xing-line',
-  'youtube-fill',
-  'youtube-line',
-  'zcool-fill',
-  'zcool-line',
-  'zhihu-fill',
-  'zhihu-line',
-  'zoom-in-fill',
-  'zoom-in-line',
-  'zoom-out-fill',
-  'zoom-out-line',
-  'zzz-fill',
-  'zzz-line',
-]
-module.exports = [
-  {
-    url: '/remixIcon/getList',
-    type: 'post',
-    response(config) {
-      const { title, pageNo = 1, pageSize = 72 } = config.body
-      let mockList = data.filter((item) => {
-        if (title && item.indexOf(title) < 0) return false
-        return true
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: mockList.length,
-        data: pageList,
-      }
-    },
-  },
-]
diff --git a/mock/controller/roleManagement.js b/mock/controller/roleManagement.js
deleted file mode 100644
index 3a2079e..0000000
--- a/mock/controller/roleManagement.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const totalCount = 2
-const List = [
-  {
-    id: '@id',
-    permission: 'admin',
-  },
-  {
-    id: '@id',
-    permission: 'editor',
-  },
-]
-module.exports = [
-  {
-    url: '/roleManagement/getList',
-    type: 'post',
-    response(config) {
-      const { title = '', pageNo = 1, pageSize = 20 } = config.body
-      let mockList = List.filter((item) => {
-        return !(title && item.title.indexOf(title) < 0)
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount,
-        data: pageList,
-      }
-    },
-  },
-  {
-    url: '/roleManagement/doEdit',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙淇濆瓨鎴愬姛',
-      }
-    },
-  },
-  {
-    url: '/roleManagement/doDelete',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙鍒犻櫎鎴愬姛',
-      }
-    },
-  },
-]
diff --git a/mock/controller/router.js b/mock/controller/router.js
deleted file mode 100644
index 16f3b26..0000000
--- a/mock/controller/router.js
+++ /dev/null
@@ -1,292 +0,0 @@
-const data = [
-  {
-    path: '/',
-    component: 'Layout',
-    redirect: 'index',
-    children: [
-      {
-        path: 'index',
-        name: 'Index',
-        component: '@/views/index/index',
-        meta: {
-          title: '棣栭〉',
-          icon: 'home',
-          affix: true,
-        },
-      },
-    ],
-  },
-  {
-    path: '/personnelManagement',
-    component: 'Layout',
-    redirect: 'noRedirect',
-    name: 'PersonnelManagement',
-    meta: { title: '浜哄憳', icon: 'users-cog', permissions: ['admin'] },
-    children: [
-      {
-        path: 'userManagement',
-        name: 'UserManagement',
-        component: '@/views/personnelManagement/userManagement/index',
-        meta: { title: '鐢ㄦ埛绠$悊' },
-      },
-      {
-        path: 'roleManagement',
-        name: 'RoleManagement',
-        component: '@/views/personnelManagement/roleManagement/index',
-        meta: { title: '瑙掕壊绠$悊' },
-      },
-      {
-        path: 'menuManagement',
-        name: 'MenuManagement',
-        component: '@/views/personnelManagement/menuManagement/index',
-        meta: { title: '鑿滃崟绠$悊', badge: 'New' },
-      },
-    ],
-  },
-  {
-    path: '/vab',
-    component: 'Layout',
-    redirect: 'noRedirect',
-    name: 'Vab',
-    alwaysShow: true,
-    meta: { title: '缁勪欢', icon: 'cloud' },
-    children: [
-      {
-        path: 'permissions',
-        name: 'Permission',
-        component: '@/views/vab/permissions/index',
-        meta: {
-          title: '鏉冮檺鎺у埗',
-          permissions: ['admin', 'editor'],
-          badge: 'New',
-        },
-      },
-      {
-        path: 'icon',
-        component: 'EmptyLayout',
-        redirect: 'noRedirect',
-        name: 'Icon',
-        meta: {
-          title: '鍥炬爣',
-          permissions: ['admin'],
-        },
-        children: [
-          {
-            path: 'awesomeIcon',
-            name: 'AwesomeIcon',
-            component: '@/views/vab/icon/index',
-            meta: { title: '甯歌鍥炬爣' },
-          },
-          {
-            path: 'colorfulIcon',
-            name: 'ColorfulIcon',
-            component: '@/views/vab/icon/colorfulIcon',
-            meta: { title: '澶氬僵鍥炬爣' },
-          },
-        ],
-      },
-      {
-        path: 'table',
-        component: '@/views/vab/table/index',
-        name: 'Table',
-        meta: {
-          title: '琛ㄦ牸',
-          permissions: ['admin'],
-        },
-      },
-      {
-        path: 'map',
-        name: 'Map',
-        component: '@/views/vab/map/index',
-        meta: { title: '鍦板浘', permissions: ['admin'], badge: 'Pro' },
-      },
-      {
-        path: 'webSocket',
-        name: 'WebSocket',
-        component: '@/views/vab/webSocket/index',
-        meta: { title: 'webSocket', permissions: ['admin'] },
-      },
-      {
-        path: 'form',
-        name: 'Form',
-        component: '@/views/vab/form/index',
-        meta: { title: '琛ㄥ崟', permissions: ['admin'] },
-      },
-      {
-        path: 'element',
-        name: 'Element',
-        component: '@/views/vab/element/index',
-        meta: { title: '甯哥敤缁勪欢', permissions: ['admin'] },
-      },
-      {
-        path: 'tree',
-        name: 'Tree',
-        component: '@/views/vab/tree/index',
-        meta: { title: '鏍�', permissions: ['admin'] },
-      },
-      {
-        path: 'verify',
-        name: 'Verify',
-        component: '@/views/vab/verify/index',
-        meta: { title: '楠岃瘉鐮�', permissions: ['admin'] },
-      },
-      {
-        path: 'menu1',
-        component: '@/views/vab/nested/menu1/index',
-        name: 'Menu1',
-        alwaysShow: true,
-        meta: {
-          title: '宓屽璺敱 1',
-          permissions: ['admin'],
-        },
-        children: [
-          {
-            path: 'menu1-1',
-            name: 'Menu1-1',
-            alwaysShow: true,
-            meta: { title: '宓屽璺敱 1-1' },
-            component: '@/views/vab/nested/menu1/menu1-1/index',
-
-            children: [
-              {
-                path: 'menu1-1-1',
-                name: 'Menu1-1-1',
-                meta: { title: '宓屽璺敱 1-1-1' },
-                component: '@/views/vab/nested/menu1/menu1-1/menu1-1-1/index',
-              },
-            ],
-          },
-        ],
-      },
-      {
-        path: 'magnifier',
-        name: 'Magnifier',
-        component: '@/views/vab/magnifier/index',
-        meta: { title: '鏀惧ぇ闀�', permissions: ['admin'] },
-      },
-      {
-        path: 'loading',
-        name: 'Loading',
-        component: '@/views/vab/loading/index',
-        meta: { title: 'loading', permissions: ['admin'] },
-      },
-      {
-        path: 'player',
-        name: 'Player',
-        component: '@/views/vab/player/index',
-        meta: { title: '瑙嗛鎾斁鍣�', permissions: ['admin'] },
-      },
-      {
-        path: 'markdownEditor',
-        name: 'MarkdownEditor',
-        component: '@/views/vab/markdownEditor/index',
-        meta: { title: 'markdown缂栬緫鍣�', permissions: ['admin'] },
-      },
-      {
-        path: 'editor',
-        name: 'Editor',
-        component: '@/views/vab/editor/index',
-        meta: { title: '瀵屾枃鏈紪杈戝櫒', permissions: ['admin'], badge: 'New' },
-      },
-      {
-        path: 'backToTop',
-        name: 'BackToTop',
-        component: '@/views/vab/backToTop/index',
-        meta: { title: '杩斿洖椤堕儴', permissions: ['admin'] },
-      },
-      {
-        path: 'lodash',
-        name: 'Lodash',
-        component: '@/views/vab/lodash/index',
-        meta: { title: 'lodash', permissions: ['admin'] },
-      },
-      {
-        path: 'smallComponents',
-        name: 'SmallComponents',
-        component: '@/views/vab/smallComponents/index',
-        meta: { title: '灏忕粍浠�', permissions: ['admin'] },
-      },
-
-      {
-        path: 'upload',
-        name: 'Upload',
-        component: '@/views/vab/upload/index',
-        meta: { title: '涓婁紶', permissions: ['admin'] },
-      },
-      {
-        path: 'log',
-        name: 'Log',
-        component: '@/views/vab/errorLog/index',
-        meta: { title: '閿欒鏃ュ織妯℃嫙', permissions: ['admin'] },
-      },
-      {
-        path: 'more',
-        name: 'More',
-        component: '@/views/vab/more/index',
-        meta: { title: '鍏充簬', permissions: ['admin'] },
-      },
-    ],
-  },
-  {
-    path: '/mall',
-    component: 'Layout',
-    redirect: 'noRedirect',
-    name: 'Mall',
-    meta: {
-      title: '鍟嗗煄',
-      icon: 'shopping-cart',
-      permissions: ['admin'],
-    },
-
-    children: [
-      {
-        path: 'pay',
-        name: 'Pay',
-        component: '@/views/mall/pay/index',
-        meta: {
-          title: '鏀粯',
-          noKeepAlive: true,
-        },
-        children: null,
-      },
-      {
-        path: 'goodsList',
-        name: 'GoodsList',
-        component: '@/views/mall/goodsList/index',
-        meta: {
-          title: '鍟嗗搧鍒楄〃',
-        },
-      },
-    ],
-  },
-  {
-    path: '/error',
-    component: 'EmptyLayout',
-    redirect: 'noRedirect',
-    name: 'Error',
-    meta: { title: '閿欒椤�', icon: 'bug' },
-    children: [
-      {
-        path: '401',
-        name: 'Error401',
-        component: '@/views/401',
-        meta: { title: '401' },
-      },
-      {
-        path: '404',
-        name: 'Error404',
-        component: '@/views/404',
-        meta: { title: '404' },
-      },
-    ],
-  },
-]
-module.exports = [
-  {
-    url: '/menu/navigate',
-    type: 'post',
-    response() {
-      return { code: 200, msg: 'success', data: data }
-    },
-  },
-]
diff --git a/mock/controller/table.js b/mock/controller/table.js
deleted file mode 100644
index 264f493..0000000
--- a/mock/controller/table.js
+++ /dev/null
@@ -1,88 +0,0 @@
-const { mock } = require('mockjs')
-const { handleRandomImage } = require('../utils')
-
-const List = []
-const count = 999
-for (let i = 0; i < count; i++) {
-  List.push(
-    mock({
-      uuid: '@uuid',
-      id: '@id',
-      title: '@csentence(1, 2)',
-      'status|1': ['published', 'draft', 'deleted'],
-      author: '@cname',
-      datetime: '@datetime',
-      pageViews: '@integer(300, 5000)',
-      img: handleRandomImage(200, 200),
-      smallImg: handleRandomImage(40, 40),
-      switch: '@boolean',
-      percent: '@integer(80,99)',
-    })
-  )
-}
-
-module.exports = [
-  {
-    url: '/table/getList',
-    type: 'post',
-    response(config) {
-      if (!config.body) {
-        return {
-          code: 200,
-          msg: 'success',
-          totalCount: count,
-          data: mock({
-            'data|50': [
-              {
-                id: '@id',
-                title: '@csentence(1, 2)',
-                'status|1': ['published', 'draft', 'deleted'],
-                author: '@cname',
-                datetime: '@datetime',
-                pageViews: '@integer(300, 5000)',
-                img: handleRandomImage(200, 200),
-                smallImg: handleRandomImage(40, 40),
-                switch: '@boolean',
-                percent: '@integer(80,99)',
-              },
-            ],
-          }).data,
-        }
-      }
-      const { title = '', pageNo = 1, pageSize = 20 } = config.body
-      let mockList = List.filter((item) => {
-        return !(title && item.title.indexOf(title) < 0)
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount: count,
-        data: pageList,
-      }
-    },
-  },
-  {
-    url: '/table/doEdit',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙淇濆瓨鎴愬姛',
-      }
-    },
-  },
-  {
-    url: '/table/doDelete',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙鍒犻櫎鎴愬姛',
-      }
-    },
-  },
-]
diff --git a/mock/controller/tree.js b/mock/controller/tree.js
deleted file mode 100644
index fc2133a..0000000
--- a/mock/controller/tree.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const data = [
-  {
-    id: '1',
-    parentId: '0',
-    name: 'root',
-    title: 'root',
-    text: 'root',
-    value: '1',
-    rank: 1,
-    children: [
-      {
-        id: '32816b88ff72423f960e7d492a386131',
-        parentId: '1',
-        name: '涓�绾�',
-        title: '涓�绾�',
-        text: '涓�绾�',
-        value: '32816b88ff72423f960e7d492a386131',
-        rank: 2,
-        children: [
-          {
-            id: '9e11afc35d55475fb0bd3164b9684cbe',
-            parentId: '32816b88ff72423f960e7d492a386131',
-            name: '浜岀骇',
-            title: '浜岀骇',
-            text: '浜岀骇',
-            value: '9e11afc35d55475fb0bd3164b9684cbe',
-            rank: 3,
-            children: [
-              {
-                id: '4cc1b04635e4444292526c5391699077',
-                parentId: '9e11afc35d55475fb0bd3164b9684cbe',
-                name: '涓夌骇',
-                title: '涓夌骇',
-                text: '涓夌骇',
-                value: '4cc1b04635e4444292526c5391699077',
-                rank: 4,
-                children: [],
-              },
-            ],
-          },
-        ],
-      },
-    ],
-  },
-]
-module.exports = [
-  {
-    url: '/tree/list',
-    type: 'post',
-    response() {
-      return { code: 200, msg: 'success', data }
-    },
-  },
-]
diff --git a/mock/controller/user.js b/mock/controller/user.js
deleted file mode 100644
index 637c7c9..0000000
--- a/mock/controller/user.js
+++ /dev/null
@@ -1,95 +0,0 @@
-const accessTokens = {
-  admin: 'admin-accessToken',
-  editor: 'editor-accessToken',
-  test: 'test-accessToken',
-}
-
-module.exports = [
-  {
-    url: '/publicKey',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: 'success',
-        data: {
-          mockServer: true,
-          publicKey:
-            'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBT2vr+dhZElF73FJ6xiP181txKWUSNLPQQlid6DUJhGAOZblluafIdLmnUyKE8mMHhT3R+Ib3ssZcJku6Hn72yHYj/qPkCGFv0eFo7G+GJfDIUeDyalBN0QsuiE/XzPHJBuJDfRArOiWvH0BXOv5kpeXSXM8yTt5Na1jAYSiQ/wIDAQAB',
-        },
-      }
-    },
-  },
-  {
-    url: '/login',
-    type: 'post',
-    response(config) {
-      const { username } = config.body
-      const accessToken = accessTokens[username]
-      if (!accessToken) {
-        return {
-          code: 500,
-          msg: '甯愭埛鎴栧瘑鐮佷笉姝g‘銆�',
-        }
-      }
-      return {
-        code: 200,
-        msg: 'success',
-        data: { accessToken },
-      }
-    },
-  },
-  {
-    url: '/register',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙娉ㄥ唽鎴愬姛',
-      }
-    },
-  },
-  {
-    url: '/userInfo',
-    type: 'post',
-    response(config) {
-      const { accessToken } = config.body
-      let permissions = ['admin']
-      let username = 'admin'
-      if ('admin-accessToken' === accessToken) {
-        permissions = ['admin']
-        username = 'admin'
-      }
-      if ('editor-accessToken' === accessToken) {
-        permissions = ['editor']
-        username = 'editor'
-      }
-      if ('test-accessToken' === accessToken) {
-        permissions = ['admin', 'editor']
-        username = 'test'
-      }
-      return {
-        code: 200,
-        msg: 'success',
-        data: {
-          permissions,
-          username,
-          'avatar|1': [
-            'https://i.gtimg.cn/club/item/face/img/2/15922_100.gif',
-            'https://i.gtimg.cn/club/item/face/img/8/15918_100.gif',
-          ],
-        },
-      }
-    },
-  },
-  {
-    url: '/logout',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: 'success',
-      }
-    },
-  },
-]
diff --git a/mock/controller/userManagement.js b/mock/controller/userManagement.js
deleted file mode 100644
index f83e701..0000000
--- a/mock/controller/userManagement.js
+++ /dev/null
@@ -1,70 +0,0 @@
-const totalCount = 3
-const List = [
-  {
-    id: '@id',
-    username: 'admin',
-    password: 'admin',
-    email: '@email',
-    permissions: ['admin'],
-    datatime: '@datetime',
-  },
-  {
-    id: '@id',
-    username: 'editor',
-    password: 'editor',
-    email: '@email',
-    permissions: ['editor'],
-    datatime: '@datetime',
-  },
-  {
-    id: '@id',
-    username: 'test',
-    password: 'test',
-    email: '@email',
-    permissions: ['admin', 'editor'],
-    datatime: '@datetime',
-  },
-]
-module.exports = [
-  {
-    url: '/userManagement/getList',
-    type: 'post',
-    response(config) {
-      const { title = '', pageNo = 1, pageSize = 20 } = config.body
-      let mockList = List.filter((item) => {
-        if (title && item.title.indexOf(title) < 0) return false
-        return true
-      })
-      const pageList = mockList.filter(
-        (item, index) =>
-          index < pageSize * pageNo && index >= pageSize * (pageNo - 1)
-      )
-      return {
-        code: 200,
-        msg: 'success',
-        totalCount,
-        data: pageList,
-      }
-    },
-  },
-  {
-    url: '/userManagement/doEdit',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙淇濆瓨鎴愬姛',
-      }
-    },
-  },
-  {
-    url: '/userManagement/doDelete',
-    type: 'post',
-    response() {
-      return {
-        code: 200,
-        msg: '妯℃嫙鍒犻櫎鎴愬姛',
-      }
-    },
-  },
-]
diff --git a/mock/index.js b/mock/index.js
deleted file mode 100644
index 1910296..0000000
--- a/mock/index.js
+++ /dev/null
@@ -1,98 +0,0 @@
-const chokidar = require('chokidar')
-const bodyParser = require('body-parser')
-const chalk = require('chalk')
-const path = require('path')
-const { mock } = require('mockjs')
-const { baseURL } = require('../src/config')
-const mockDir = path.join(process.cwd(), 'mock')
-const { handleMockArray } = require('./utils')
-
-/**
- *
- * @param app
- * @returns {{mockStartIndex: number, mockRoutesLength: number}}
- */
-const registerRoutes = (app) => {
-  let mockLastIndex
-  const mocks = []
-  const mockArray = handleMockArray()
-  mockArray.forEach((item) => {
-    const obj = require(item)
-    mocks.push(...obj)
-  })
-  const mocksForServer = mocks.map((route) => {
-    return responseFake(route.url, route.type, route.response)
-  })
-  for (const mock of mocksForServer) {
-    app[mock.type](mock.url, mock.response)
-    mockLastIndex = app._router.stack.length
-  }
-  const mockRoutesLength = Object.keys(mocksForServer).length
-  return {
-    mockRoutesLength: mockRoutesLength,
-    mockStartIndex: mockLastIndex - mockRoutesLength,
-  }
-}
-
-/**
- *
- * @param url
- * @param type
- * @param respond
- * @returns {{response(*=, *=): void, type: (*|string), url: RegExp}}
- */
-const responseFake = (url, type, respond) => {
-  return {
-    url: new RegExp(`${baseURL}${url}`),
-    type: type || 'get',
-    response(req, res) {
-      res.status(200)
-      if (JSON.stringify(req.body) !== '{}') {
-        console.log(chalk.green(`> 璇锋眰鍦板潃锛�${req.path}`))
-        console.log(chalk.green(`> 璇锋眰鍙傛暟锛�${JSON.stringify(req.body)}\n`))
-      } else {
-        console.log(chalk.green(`> 璇锋眰鍦板潃锛�${req.path}\n`))
-      }
-      res.json(mock(respond instanceof Function ? respond(req, res) : respond))
-    },
-  }
-}
-/**
- *
- * @param app
- */
-module.exports = (app) => {
-  app.use(bodyParser.json())
-  app.use(
-    bodyParser.urlencoded({
-      extended: true,
-    })
-  )
-
-  const mockRoutes = registerRoutes(app)
-  let mockRoutesLength = mockRoutes.mockRoutesLength
-  let mockStartIndex = mockRoutes.mockStartIndex
-  chokidar
-    .watch(mockDir, {
-      ignored: /mock-server/,
-      ignoreInitial: true,
-    })
-    .on('all', (event) => {
-      if (event === 'change' || event === 'add') {
-        try {
-          app._router.stack.splice(mockStartIndex, mockRoutesLength)
-
-          Object.keys(require.cache).forEach((item) => {
-            if (item.includes(mockDir)) {
-              delete require.cache[require.resolve(item)]
-            }
-          })
-          const mockRoutes = registerRoutes(app)
-          mockRoutesLength = mockRoutes.mockRoutesLength
-          mockStartIndex = mockRoutes.mockStartIndex
-        } catch (error) {
-          console.log(chalk.red(error))
-        }
-      }
-    })
-}
diff --git a/mock/utils/index.js b/mock/utils/index.js
deleted file mode 100644
index 840cdac..0000000
--- a/mock/utils/index.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const { Random } = require('mockjs')
-const { join } = require('path')
-const fs = require('fs')
-
-/**
- * @author chuzhixin 1204505056@qq.com 锛堜笉鎯充繚鐣檃uthor鍙垹闄わ級
- * @description 闅忔満鐢熸垚鍥剧墖url銆�
- * @param width
- * @param height
- * @returns {string}
- */
-function handleRandomImage(width = 50, height = 50) {
-  return `https://picsum.photos/${width}/${height}?random=${Random.guid()}`
-}
-
-/**
- * @author chuzhixin 1204505056@qq.com 锛堜笉鎯充繚鐣檃uthor鍙垹闄わ級
- * @description 澶勭悊鎵�鏈� controller 妯″潡锛宯pm run serve鏃跺湪node鐜涓嚜鍔ㄨ緭鍑篶ontroller鏂囦欢澶逛笅Mock鎺ュ彛锛岃鍕夸慨鏀广��
- * @returns {[]}
- */
-function handleMockArray() {
-  const mockArray = []
-  const getFiles = (jsonPath) => {
-    const jsonFiles = []
-    const findJsonFile = (path) => {
-      const files = fs.readdirSync(path)
-      files.forEach((item) => {
-        const fPath = join(path, item)
-        const stat = fs.statSync(fPath)
-        if (stat.isDirectory() === true) findJsonFile(item)
-        if (stat.isFile() === true) jsonFiles.push(item)
-      })
-    }
-    findJsonFile(jsonPath)
-    jsonFiles.forEach((item) => mockArray.push(`./controller/${item}`))
-  }
-  getFiles('mock/controller')
-  return mockArray
-}
-module.exports = {
-  handleRandomImage,
-  handleMockArray,
-}
diff --git a/src/api/package.js b/src/api/package.js
index 4961f46..942ef48 100644
--- a/src/api/package.js
+++ b/src/api/package.js
@@ -8,6 +8,14 @@
   });
 }
 
+export function rebuild(data) {
+  return request({
+    url: "/package/" + data.id + "/rebuild",
+    method: "post",
+    data,
+  });
+}
+
 export function download(query) {
   return request({
     url: "/package/download",
diff --git a/src/api/user.js b/src/api/user.js
index dce05f1..dd36086 100644
--- a/src/api/user.js
+++ b/src/api/user.js
@@ -1,11 +1,17 @@
 import request from "@/utils/request";
-import { loginRSA, tokenName } from "@/config";
 
 export async function login(data) {
   return request({
-    url: "/user/login",
+    url: "/account/login",
     method: "post",
     data,
+  });
+}
+
+export function logout() {
+  return request({
+    url: "/account/logout",
+    method: "post",
   });
 }
 
@@ -13,22 +19,44 @@
   return request({
     url: "/user/info",
     method: "post",
-    data: {
-      [tokenName]: accessToken,
-    },
   });
 }
 
-export function logout() {
+export function register(data) {
   return request({
-    url: "/logout",
+    url: "/user/register",
     method: "post",
+    data,
   });
 }
 
-export function register() {
+export function doEdit(data) {
   return request({
-    url: "/register",
+    url: "/user/" + data.id,
+    method: "put",
+    data,
+  });
+}
+
+export function getUsers(query) {
+  return request({
+    url: "/user/list",
+    method: "get",
+    params: query,
+  });
+}
+
+export function deleteUser(id) {
+  return request({
+    url: "/user/" + id,
+    method: "delete",
+  });
+}
+
+export function updatePassword(id, data) {
+  return request({
+    url: "/user/" + id + "/password",
     method: "post",
+    data,
   });
 }
diff --git a/src/components/SelectTree/index.vue b/src/components/SelectTree/index.vue
index bacc7dd..d683143 100644
--- a/src/components/SelectTree/index.vue
+++ b/src/components/SelectTree/index.vue
@@ -31,168 +31,168 @@
 </template>
 
 <script>
-  export default {
-    name: 'SelectTreeTemplate',
-    props: {
-      /* 鏍戝舰缁撴瀯鏁版嵁 */
-      treeOptions: {
-        type: Array,
-        default: () => {
-          return []
-        },
-      },
-      /* 鍗曢��/澶氶�� */
-      selectType: {
-        type: String,
-        default: () => {
-          return 'single'
-        },
-      },
-      /* 鍒濆閫変腑鍊糼ey */
-      selectedKey: {
-        type: String,
-        default: () => {
-          return ''
-        },
-      },
-      /* 鍒濆閫変腑鍊糿ame */
-      selectedValue: {
-        type: String,
-        default: () => {
-          return ''
-        },
-      },
-      /* 鍙仛閫夋嫨鐨勫眰绾� */
-      selectLevel: {
-        type: [String, Number],
-        default: () => {
-          return ''
-        },
-      },
-      /* 鍙竻绌洪�夐」 */
-      clearable: {
-        type: Boolean,
-        default: () => {
-          return true
-        },
+export default {
+  name: "SelectTreeTemplate",
+  props: {
+    /* 鏍戝舰缁撴瀯鏁版嵁 */
+    treeOptions: {
+      type: Array,
+      default: () => {
+        return [];
       },
     },
-    data() {
-      return {
-        defaultProps: {
-          children: 'children',
-          label: 'name',
-        },
-        defaultSelectedKeys: [], //鍒濆閫変腑鍊兼暟缁�
-        currentNodeKey: this.selectedKey,
-        selectValue:
-          this.selectType == 'multiple'
-            ? this.selectedValue.split(',')
-            : this.selectedValue, //涓嬫媺妗嗛�変腑鍊糽abel
-        selectKey:
-          this.selectType == 'multiple'
-            ? this.selectedKey.split(',')
-            : this.selectedKey, //涓嬫媺妗嗛�変腑鍊紇alue
+    /* 鍗曢��/澶氶�� */
+    selectType: {
+      type: String,
+      default: () => {
+        return "single";
+      },
+    },
+    /* 鍒濆閫変腑鍊糼ey */
+    selectedKey: {
+      type: String,
+      default: () => {
+        return "";
+      },
+    },
+    /* 鍒濆閫変腑鍊糿ame */
+    selectedValue: {
+      type: String,
+      default: () => {
+        return "";
+      },
+    },
+    /* 鍙仛閫夋嫨鐨勫眰绾� */
+    selectLevel: {
+      type: [String, Number],
+      default: () => {
+        return "";
+      },
+    },
+    /* 鍙竻绌洪�夐」 */
+    clearable: {
+      type: Boolean,
+      default: () => {
+        return true;
+      },
+    },
+  },
+  data() {
+    return {
+      defaultProps: {
+        children: "children",
+        label: "name",
+      },
+      defaultSelectedKeys: [], //鍒濆閫変腑鍊兼暟缁�
+      currentNodeKey: this.selectedKey,
+      selectValue:
+        this.selectType == "multiple"
+          ? this.selectedValue.split(",")
+          : this.selectedValue, //涓嬫媺妗嗛�変腑鍊糽abel
+      selectKey:
+        this.selectType == "multiple"
+          ? this.selectedKey.split(",")
+          : this.selectedKey, //涓嬫媺妗嗛�変腑鍊紇alue
+    };
+  },
+  mounted() {
+    const that = this;
+    this.initTree();
+  },
+  methods: {
+    // 鍒濆鍖栨爲鐨勫��
+    initTree() {
+      const that = this;
+      if (that.selectedKey) {
+        that.defaultSelectedKeys = that.selectedKey.split(","); // 璁剧疆榛樿灞曞紑
+        if (that.selectType == "single") {
+          that.$refs.treeOption.setCurrentKey(that.selectedKey); // 璁剧疆榛樿閫変腑
+        } else {
+          that.$refs.treeOption.setCheckedKeys(that.defaultSelectedKeys);
+        }
       }
     },
-    mounted() {
-      const that = this
-      this.initTree()
+    // 娓呴櫎閫変腑
+    clearHandle() {
+      const that = this;
+      this.selectValue = "";
+      this.selectKey = "";
+      this.defaultSelectedKeys = [];
+      this.currentNodeKey = "";
+      this.clearSelected();
+      if (that.selectType == "single") {
+        that.$refs.treeOption.setCurrentKey(""); // 璁剧疆榛樿閫変腑
+      } else {
+        that.$refs.treeOption.setCheckedKeys([]);
+      }
     },
-    methods: {
-      // 鍒濆鍖栨爲鐨勫��
-      initTree() {
-        const that = this
-        if (that.selectedKey) {
-          that.defaultSelectedKeys = that.selectedKey.split(',') // 璁剧疆榛樿灞曞紑
-          if (that.selectType == 'single') {
-            that.$refs.treeOption.setCurrentKey(that.selectedKey) // 璁剧疆榛樿閫変腑
-          } else {
-            that.$refs.treeOption.setCheckedKeys(that.defaultSelectedKeys)
-          }
-        }
-      },
-      // 娓呴櫎閫変腑
-      clearHandle() {
-        const that = this
-        this.selectValue = ''
-        this.selectKey = ''
-        this.defaultSelectedKeys = []
-        this.currentNodeKey = ''
-        this.clearSelected()
-        if (that.selectType == 'single') {
-          that.$refs.treeOption.setCurrentKey('') // 璁剧疆榛樿閫変腑
-        } else {
-          that.$refs.treeOption.setCheckedKeys([])
-        }
-      },
-      /* 娓呯┖閫変腑鏍峰紡 */
-      clearSelected() {
-        const allNode = document.querySelectorAll('#treeOption .el-tree-node')
-        allNode.forEach((element) => element.classList.remove('is-current'))
-      },
-      // select澶氶�夋椂绉婚櫎鏌愰」鎿嶄綔
-      removeTag(val) {
-        this.$refs.treeOption.setCheckedKeys([])
-      },
-      // 鐐瑰嚮鍙跺瓙鑺傜偣
-      nodeClick(data, node, el) {
-        if (data.rank >= this.selectLevel) {
-          this.selectValue = data.name
-          this.selectKey = data.id
-        }
-      },
-      // 鑺傜偣閫変腑鎿嶄綔
-      checkNode(data, node, el) {
-        const checkedNodes = this.$refs.treeOption.getCheckedNodes()
-        const keyArr = []
-        const valueArr = []
-        checkedNodes.forEach((item) => {
-          if (item.rank >= this.selectLevel) {
-            keyArr.push(item.id)
-            valueArr.push(item.name)
-          }
-        })
-        this.selectValue = valueArr
-        this.selectKey = keyArr
-      },
+    /* 娓呯┖閫変腑鏍峰紡 */
+    clearSelected() {
+      const allNode = document.querySelectorAll("#treeOption .el-tree-node");
+      allNode.forEach((element) => element.classList.remove("is-current"));
     },
-  }
+    // select澶氶�夋椂绉婚櫎鏌愰」鎿嶄綔
+    removeTag(val) {
+      this.$refs.treeOption.setCheckedKeys([]);
+    },
+    // 鐐瑰嚮鍙跺瓙鑺傜偣
+    nodeClick(data, node, el) {
+      if (data.rank >= this.selectLevel) {
+        this.selectValue = data.name;
+        this.selectKey = data.id;
+      }
+    },
+    // 鑺傜偣閫変腑鎿嶄綔
+    checkNode(data, node, el) {
+      const checkedNodes = this.$refs.treeOption.getCheckedNodes();
+      const keyArr = [];
+      const valueArr = [];
+      checkedNodes.forEach((item) => {
+        if (item.rank >= this.selectLevel) {
+          keyArr.push(item.id);
+          valueArr.push(item.name);
+        }
+      });
+      this.selectValue = valueArr;
+      this.selectKey = keyArr;
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
-    height: auto;
-    max-height: 274px;
-    padding: 0;
-    overflow-y: auto;
-  }
+.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
+  height: auto;
+  max-height: 274px;
+  padding: 0;
+  overflow-y: auto;
+}
 
-  .el-select-dropdown__item.selected {
-    font-weight: normal;
-  }
+.el-select-dropdown__item.selected {
+  font-weight: normal;
+}
 
-  ul li > .el-tree .el-tree-node__content {
-    height: auto;
-    padding: 0 20px;
-  }
+ul li > .el-tree .el-tree-node__content {
+  height: auto;
+  padding: 0 20px;
+}
 
-  .el-tree-node__label {
-    font-weight: normal;
-  }
+.el-tree-node__label {
+  font-weight: normal;
+}
 
-  .el-tree > .is-current .el-tree-node__label {
-    font-weight: 700;
-    color: #409eff;
-  }
+.el-tree > .is-current .el-tree-node__label {
+  font-weight: 700;
+  color: #409eff;
+}
 
-  .el-tree > .is-current .el-tree-node__children .el-tree-node__label {
-    font-weight: normal;
-    color: #606266;
-  }
+.el-tree > .is-current .el-tree-node__children .el-tree-node__label {
+  font-weight: normal;
+  color: #606266;
+}
 </style>
 <style lang="scss">
-  /* .vab-tree-select{
+/* .vab-tree-select{
       .el-tag__close.el-icon-close{
         width:0;
         overflow:hidden;
diff --git a/src/components/VabCharge/index.vue b/src/components/VabCharge/index.vue
index 609da97..14950e9 100644
--- a/src/components/VabCharge/index.vue
+++ b/src/components/VabCharge/index.vue
@@ -23,169 +23,169 @@
 </template>
 
 <script>
-  export default {
-    name: 'VabCharge',
-    props: {
-      styleObj: {
-        type: Object,
-        default: () => {
-          return {}
-        },
-      },
-      startVal: {
-        type: Number,
-        default: 0,
-      },
-      endVal: {
-        type: Number,
-        default: 100,
+export default {
+  name: "VabCharge",
+  props: {
+    styleObj: {
+      type: Object,
+      default: () => {
+        return {};
       },
     },
-    data() {
-      return {
-        decimals: 2,
-        prefix: '',
-        suffix: '%',
-        separator: ',',
-        duration: 3000,
-      }
+    startVal: {
+      type: Number,
+      default: 0,
     },
-    created() {},
-    mounted() {},
-    methods: {},
-  }
+    endVal: {
+      type: Number,
+      default: 100,
+    },
+  },
+  data() {
+    return {
+      decimals: 2,
+      prefix: "",
+      suffix: "%",
+      separator: ",",
+      duration: 3000,
+    };
+  },
+  created() {},
+  mounted() {},
+  methods: {},
+};
 </script>
 
 <style lang="scss" scoped>
-  .content {
+.content {
+  position: relative;
+  display: flex;
+  align-items: center; /* 鍨傜洿灞呬腑 */
+  justify-content: center; /* 姘村钩灞呬腑 */
+  width: 100%;
+  background: #000;
+
+  .g-number {
+    position: absolute;
+    top: 27%;
+    z-index: 99;
+    width: 300px;
+    font-size: 32px;
+    color: #fff;
+    text-align: center;
+  }
+
+  .g-container {
     position: relative;
-    display: flex;
-    align-items: center; /* 鍨傜洿灞呬腑 */
-    justify-content: center; /* 姘村钩灞呬腑 */
-    width: 100%;
-    background: #000;
+    width: 300px;
+    height: 400px;
+    margin: auto;
+  }
 
-    .g-number {
+  .g-contrast {
+    width: 300px;
+    height: 400px;
+    overflow: hidden;
+    background-color: #000;
+    filter: contrast(15) hue-rotate(0);
+    animation: hueRotate 10s infinite linear;
+  }
+
+  .g-circle {
+    position: relative;
+    box-sizing: border-box;
+    width: 300px;
+    height: 300px;
+    filter: blur(8px);
+
+    &::after {
       position: absolute;
-      top: 27%;
-      z-index: 99;
-      width: 300px;
-      font-size: 32px;
-      color: #fff;
-      text-align: center;
-    }
-
-    .g-container {
-      position: relative;
-      width: 300px;
-      height: 400px;
-      margin: auto;
-    }
-
-    .g-contrast {
-      width: 300px;
-      height: 400px;
-      overflow: hidden;
-      background-color: #000;
-      filter: contrast(15) hue-rotate(0);
-      animation: hueRotate 10s infinite linear;
-    }
-
-    .g-circle {
-      position: relative;
-      box-sizing: border-box;
-      width: 300px;
-      height: 300px;
-      filter: blur(8px);
-
-      &::after {
-        position: absolute;
-        top: 40%;
-        left: 50%;
-        width: 200px;
-        height: 200px;
-        content: '';
-        background-color: #00ff6f;
-        border-radius: 42% 38% 62% 49% / 45%;
-        transform: translate(-50%, -50%) rotate(0);
-        animation: rotate 10s infinite linear;
-      }
-
-      &::before {
-        position: absolute;
-        top: 40%;
-        left: 50%;
-        z-index: 99;
-        width: 176px;
-        height: 176px;
-        content: '';
-        background-color: #000;
-        border-radius: 50%;
-        transform: translate(-50%, -50%);
-      }
-    }
-
-    .g-bubbles {
-      position: absolute;
-      bottom: 0;
+      top: 40%;
       left: 50%;
-      width: 100px;
-      height: 40px;
+      width: 200px;
+      height: 200px;
+      content: "";
       background-color: #00ff6f;
-      filter: blur(5px);
-      border-radius: 100px 100px 0 0;
-      transform: translate(-50%, 0);
+      border-radius: 42% 38% 62% 49% / 45%;
+      transform: translate(-50%, -50%) rotate(0);
+      animation: rotate 10s infinite linear;
     }
 
-    li {
+    &::before {
       position: absolute;
-      background: #00ff6f;
+      top: 40%;
+      left: 50%;
+      z-index: 99;
+      width: 176px;
+      height: 176px;
+      content: "";
+      background-color: #000;
       border-radius: 50%;
-    }
-
-    @for $i from 0 through 15 {
-      li:nth-child(#{$i}) {
-        $width: 15 + random(15) + px;
-
-        top: 50%;
-        left: 15 + random(70) + px;
-        width: $width;
-        height: $width;
-        transform: translate(-50%, -50%);
-        animation: moveToTop
-          #{random(6) +
-          3}s
-          ease-in-out -#{random(5000) /
-          1000}s
-          infinite;
-      }
-    }
-
-    @keyframes rotate {
-      50% {
-        border-radius: 45% / 42% 38% 58% 49%;
-      }
-
-      100% {
-        transform: translate(-50%, -50%) rotate(720deg);
-      }
-    }
-
-    @keyframes moveToTop {
-      90% {
-        opacity: 1;
-      }
-
-      100% {
-        opacity: 0.1;
-        transform: translate(-50%, -180px);
-      }
-    }
-
-    @keyframes hueRotate {
-      100% {
-        filter: contrast(15) hue-rotate(360deg);
-      }
+      transform: translate(-50%, -50%);
     }
   }
+
+  .g-bubbles {
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    width: 100px;
+    height: 40px;
+    background-color: #00ff6f;
+    filter: blur(5px);
+    border-radius: 100px 100px 0 0;
+    transform: translate(-50%, 0);
+  }
+
+  li {
+    position: absolute;
+    background: #00ff6f;
+    border-radius: 50%;
+  }
+
+  @for $i from 0 through 15 {
+    li:nth-child(#{$i}) {
+      $width: 15 + random(15) + px;
+
+      top: 50%;
+      left: 15 + random(70) + px;
+      width: $width;
+      height: $width;
+      transform: translate(-50%, -50%);
+      animation: moveToTop
+        #{random(6) +
+        3}s
+        ease-in-out -#{random(5000) /
+        1000}s
+        infinite;
+    }
+  }
+
+  @keyframes rotate {
+    50% {
+      border-radius: 45% / 42% 38% 58% 49%;
+    }
+
+    100% {
+      transform: translate(-50%, -50%) rotate(720deg);
+    }
+  }
+
+  @keyframes moveToTop {
+    90% {
+      opacity: 1;
+    }
+
+    100% {
+      opacity: 0.1;
+      transform: translate(-50%, -180px);
+    }
+  }
+
+  @keyframes hueRotate {
+    100% {
+      filter: contrast(15) hue-rotate(360deg);
+    }
+  }
+}
 </style>
diff --git a/src/components/VabProfile/index.vue b/src/components/VabProfile/index.vue
index 7f291dd..f91e881 100644
--- a/src/components/VabProfile/index.vue
+++ b/src/components/VabProfile/index.vue
@@ -25,289 +25,289 @@
 </template>
 
 <script>
-  export default {
-    name: 'VabProfile',
-    props: {
-      styleObj: {
-        type: Object,
-        default: () => {
-          return {}
-        },
-      },
-      username: {
-        type: String,
-        default: '',
-      },
-      avatar: {
-        type: String,
-        default: '',
-      },
-      iconArray: {
-        type: Array,
-        default: () => {
-          return [
-            { icon: 'bell', url: '' },
-            { icon: 'bookmark', url: '' },
-            { icon: 'cloud-sun', url: '' },
-          ]
-        },
+export default {
+  name: "VabProfile",
+  props: {
+    styleObj: {
+      type: Object,
+      default: () => {
+        return {};
       },
     },
-    data() {
-      return {}
+    username: {
+      type: String,
+      default: "",
     },
-    created() {},
-    mounted() {},
-    methods: {},
-  }
+    avatar: {
+      type: String,
+      default: "",
+    },
+    iconArray: {
+      type: Array,
+      default: () => {
+        return [
+          { icon: "bell", url: "" },
+          { icon: "bookmark", url: "" },
+          { icon: "cloud-sun", url: "" },
+        ];
+      },
+    },
+  },
+  data() {
+    return {};
+  },
+  created() {},
+  mounted() {},
+  methods: {},
+};
 </script>
 
 <style lang="scss" scoped>
-  .card {
-    --card-bg-color: hsl(240, 31%, 25%);
-    --card-bg-color-transparent: hsla(240, 31%, 25%, 0.7);
+.card {
+  --card-bg-color: hsl(240, 31%, 25%);
+  --card-bg-color-transparent: hsla(240, 31%, 25%, 0.7);
 
-    position: relative;
+  position: relative;
+  width: 100%;
+  height: 100%;
+
+  .card-borders {
+    position: absolute;
+    top: 0;
+    left: 0;
     width: 100%;
     height: 100%;
+    overflow: hidden;
 
-    .card-borders {
+    .border-top {
       position: absolute;
       top: 0;
-      left: 0;
       width: 100%;
+      height: 2px;
+      background: var(--card-bg-color);
+      transform: translateX(-100%);
+      animation: slide-in-horizontal 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
+        forwards;
+    }
+
+    .border-right {
+      position: absolute;
+      right: 0;
+      width: 2px;
       height: 100%;
-      overflow: hidden;
+      background: var(--card-bg-color);
+      transform: translateY(100%);
+      animation: slide-in-vertical 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
+        forwards;
+    }
 
-      .border-top {
+    .border-bottom {
+      position: absolute;
+      bottom: 0;
+      width: 100%;
+      height: 2px;
+      background: var(--card-bg-color);
+      transform: translateX(100%);
+      animation: slide-in-horizontal-reverse 0.8s
+        cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
+    }
+
+    .border-left {
+      position: absolute;
+      top: 0;
+      width: 2px;
+      height: 100%;
+      background: var(--card-bg-color);
+      transform: translateY(-100%);
+      animation: slide-in-vertical-reverse 0.8s
+        cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
+    }
+  }
+
+  .card-content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    height: 100%;
+    padding: 40px 0 40px 0;
+    background: var(--card-bg-color-transparent);
+    opacity: 0;
+    transform: scale(0.6);
+    animation: bump-in 0.5s 0.8s forwards;
+
+    .avatar {
+      width: 80px;
+      height: 80px;
+      border: 1px solid $base-color-white;
+      border-radius: 50%;
+      opacity: 0;
+      transform: scale(0.6);
+      animation: bump-in 0.5s 1s forwards;
+    }
+
+    .username {
+      position: relative;
+      margin-top: 20px;
+      margin-bottom: 20px;
+      font-size: 26px;
+      color: transparent;
+      letter-spacing: 2px;
+      animation: fill-text-white 1.2s 2s forwards;
+
+      &::before {
         position: absolute;
         top: 0;
+        left: 0;
         width: 100%;
-        height: 2px;
-        background: var(--card-bg-color);
-        transform: translateX(-100%);
-        animation: slide-in-horizontal 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
-          forwards;
-      }
-
-      .border-right {
-        position: absolute;
-        right: 0;
-        width: 2px;
         height: 100%;
-        background: var(--card-bg-color);
-        transform: translateY(100%);
-        animation: slide-in-vertical 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
-          forwards;
-      }
-
-      .border-bottom {
-        position: absolute;
-        bottom: 0;
-        width: 100%;
-        height: 2px;
-        background: var(--card-bg-color);
-        transform: translateX(100%);
-        animation: slide-in-horizontal-reverse 0.8s
-          cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
-      }
-
-      .border-left {
-        position: absolute;
-        top: 0;
-        width: 2px;
-        height: 100%;
-        background: var(--card-bg-color);
-        transform: translateY(-100%);
-        animation: slide-in-vertical-reverse 0.8s
-          cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
+        color: black;
+        content: "";
+        background: #35b9f1;
+        transform: scaleX(0);
+        transform-origin: left;
+        animation: slide-in-out 1.2s 1.2s cubic-bezier(0.75, 0, 0, 1) forwards;
       }
     }
 
-    .card-content {
+    .social-icons {
       display: flex;
-      flex-direction: column;
-      align-items: center;
-      height: 100%;
-      padding: 40px 0 40px 0;
-      background: var(--card-bg-color-transparent);
-      opacity: 0;
-      transform: scale(0.6);
-      animation: bump-in 0.5s 0.8s forwards;
 
-      .avatar {
-        width: 80px;
-        height: 80px;
-        border: 1px solid $base-color-white;
-        border-radius: 50%;
-        opacity: 0;
-        transform: scale(0.6);
-        animation: bump-in 0.5s 1s forwards;
-      }
-
-      .username {
+      .social-icon {
         position: relative;
-        margin-top: 20px;
-        margin-bottom: 20px;
-        font-size: 26px;
-        color: transparent;
-        letter-spacing: 2px;
-        animation: fill-text-white 1.2s 2s forwards;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 2.5em;
+        height: 2.5em;
+        margin: 0 15px;
+        color: white;
+        text-decoration: none;
+        border-radius: 50%;
 
-        &::before {
+        @for $i from 1 through 3 {
+          &:nth-child(#{$i}) {
+            &::before {
+              animation-delay: 2s + 0.1s * $i;
+            }
+
+            &::after {
+              animation-delay: 2.1s + 0.1s * $i;
+            }
+
+            svg {
+              animation-delay: 2.2s + 0.1s * $i;
+            }
+          }
+        }
+
+        &::before,
+        &::after {
           position: absolute;
           top: 0;
           left: 0;
           width: 100%;
           height: 100%;
-          color: black;
-          content: '';
-          background: #35b9f1;
-          transform: scaleX(0);
-          transform-origin: left;
-          animation: slide-in-out 1.2s 1.2s cubic-bezier(0.75, 0, 0, 1) forwards;
+          content: "";
+          border-radius: inherit;
+          transform: scale(0);
         }
-      }
 
-      .social-icons {
-        display: flex;
+        &::before {
+          background: #f7f1e3;
+          animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
+        }
 
-        .social-icon {
-          position: relative;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          width: 2.5em;
-          height: 2.5em;
-          margin: 0 15px;
-          color: white;
-          text-decoration: none;
-          border-radius: 50%;
+        &::after {
+          background: #2c3e50;
+          animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
+        }
 
-          @for $i from 1 through 3 {
-            &:nth-child(#{$i}) {
-              &::before {
-                animation-delay: 2s + 0.1s * $i;
-              }
-
-              &::after {
-                animation-delay: 2.1s + 0.1s * $i;
-              }
-
-              svg {
-                animation-delay: 2.2s + 0.1s * $i;
-              }
-            }
-          }
-
-          &::before,
-          &::after {
-            position: absolute;
-            top: 0;
-            left: 0;
-            width: 100%;
-            height: 100%;
-            content: '';
-            border-radius: inherit;
-            transform: scale(0);
-          }
-
-          &::before {
-            background: #f7f1e3;
-            animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
-          }
-
-          &::after {
-            background: #2c3e50;
-            animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
-          }
-
-          svg {
-            z-index: 99;
-            transform: scale(0);
-            animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
-          }
+        svg {
+          z-index: 99;
+          transform: scale(0);
+          animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
         }
       }
     }
   }
+}
 
-  @keyframes bump-in {
-    50% {
-      transform: scale(1.05);
-    }
-
-    to {
-      opacity: 1;
-      transform: scale(1);
-    }
+@keyframes bump-in {
+  50% {
+    transform: scale(1.05);
   }
 
-  @keyframes slide-in-horizontal {
-    50% {
-      transform: translateX(0);
-    }
+  to {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
 
-    to {
-      transform: translateX(100%);
-    }
+@keyframes slide-in-horizontal {
+  50% {
+    transform: translateX(0);
   }
 
-  @keyframes slide-in-horizontal-reverse {
-    50% {
-      transform: translateX(0);
-    }
+  to {
+    transform: translateX(100%);
+  }
+}
 
-    to {
-      transform: translateX(-100%);
-    }
+@keyframes slide-in-horizontal-reverse {
+  50% {
+    transform: translateX(0);
   }
 
-  @keyframes slide-in-vertical {
-    50% {
-      transform: translateY(0);
-    }
+  to {
+    transform: translateX(-100%);
+  }
+}
 
-    to {
-      transform: translateY(-100%);
-    }
+@keyframes slide-in-vertical {
+  50% {
+    transform: translateY(0);
   }
 
-  @keyframes slide-in-vertical-reverse {
-    50% {
-      transform: translateY(0);
-    }
+  to {
+    transform: translateY(-100%);
+  }
+}
 
-    to {
-      transform: translateY(100%);
-    }
+@keyframes slide-in-vertical-reverse {
+  50% {
+    transform: translateY(0);
   }
 
-  @keyframes slide-in-out {
-    50% {
-      transform: scaleX(1);
-      transform-origin: left;
-    }
+  to {
+    transform: translateY(100%);
+  }
+}
 
-    50.1% {
-      transform-origin: right;
-    }
-
-    100% {
-      transform: scaleX(0);
-      transform-origin: right;
-    }
+@keyframes slide-in-out {
+  50% {
+    transform: scaleX(1);
+    transform-origin: left;
   }
 
-  @keyframes fill-text-white {
-    to {
-      color: white;
-    }
+  50.1% {
+    transform-origin: right;
   }
 
-  @keyframes scale-in {
-    to {
-      transform: scale(1);
-    }
+  100% {
+    transform: scaleX(0);
+    transform-origin: right;
   }
+}
+
+@keyframes fill-text-white {
+  to {
+    color: white;
+  }
+}
+
+@keyframes scale-in {
+  to {
+    transform: scale(1);
+  }
+}
 </style>
diff --git a/src/components/VabSnow/index.vue b/src/components/VabSnow/index.vue
index 5131d52..badcbb2 100644
--- a/src/components/VabSnow/index.vue
+++ b/src/components/VabSnow/index.vue
@@ -5,78 +5,77 @@
 </template>
 
 <script>
-  export default {
-    name: 'VabSnow',
-    props: {
-      styleObj: {
-        type: Object,
-        default: () => {
-          return {}
-        },
+export default {
+  name: "VabSnow",
+  props: {
+    styleObj: {
+      type: Object,
+      default: () => {
+        return {};
       },
     },
-    data() {
-      return {}
-    },
-    created() {},
-    mounted() {},
-    methods: {},
-  }
+  },
+  data() {
+    return {};
+  },
+  created() {},
+  mounted() {},
+  methods: {},
+};
 </script>
 
 <style lang="scss" scoped>
-  .content {
-    position: relative;
-    width: 100%;
-    height: 100%;
-    overflow: hidden;
-    background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
-    filter: drop-shadow(0 0 10px white);
-  }
+.content {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
+  filter: drop-shadow(0 0 10px white);
+}
 
-  @function random_range($min, $max) {
-    $rand: random();
-    $random_range: $min + floor($rand * (($max - $min) + 1));
+@function random_range($min, $max) {
+  $rand: random();
+  $random_range: $min + floor($rand * (($max - $min) + 1));
 
-    @return $random_range;
-  }
+  @return $random_range;
+}
 
-  .snow {
-    $total: 200;
+.snow {
+  $total: 200;
 
-    position: absolute;
-    width: 10px;
-    height: 10px;
-    background: white;
-    border-radius: 50%;
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  background: white;
+  border-radius: 50%;
 
-    @for $i from 1 through $total {
-      $random-x: random(1000000) * 0.0001vw;
-      $random-offset: random_range(-100000, 100000) * 0.0001vw;
-      $random-x-end: $random-x + $random-offset;
-      $random-x-end-yoyo: $random-x + ($random-offset / 2);
-      $random-yoyo-time: random_range(30000, 80000) / 100000;
-      $random-yoyo-y: $random-yoyo-time * 100vh;
-      $random-scale: random(10000) * 0.0001;
-      $fall-duration: random_range(10, 30) * 1s;
-      $fall-delay: random(30) * -1s;
+  @for $i from 1 through $total {
+    $random-x: random(1000000) * 0.0001vw;
+    $random-offset: random_range(-100000, 100000) * 0.0001vw;
+    $random-x-end: $random-x + $random-offset;
+    $random-x-end-yoyo: $random-x + ($random-offset / 2);
+    $random-yoyo-time: random_range(30000, 80000) / 100000;
+    $random-yoyo-y: $random-yoyo-time * 100vh;
+    $random-scale: random(10000) * 0.0001;
+    $fall-duration: random_range(10, 30) * 1s;
+    $fall-delay: random(30) * -1s;
 
-      &:nth-child(#{$i}) {
-        opacity: random(10000) * 0.0001;
-        transform: translate($random-x, -10px) scale($random-scale);
-        animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
+    &:nth-child(#{$i}) {
+      opacity: random(10000) * 0.0001;
+      transform: translate($random-x, -10px) scale($random-scale);
+      animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
+    }
+
+    @keyframes fall-#{$i} {
+      #{percentage($random-yoyo-time)} {
+        transform: translate($random-x-end, $random-yoyo-y) scale($random-scale);
       }
 
-      @keyframes fall-#{$i} {
-        #{percentage($random-yoyo-time)} {
-          transform: translate($random-x-end, $random-yoyo-y)
-            scale($random-scale);
-        }
-
-        to {
-          transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
-        }
+      to {
+        transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
       }
     }
   }
+}
 </style>
diff --git a/src/components/VabUpload/index.vue b/src/components/VabUpload/index.vue
index 31d83a5..a8c6412 100644
--- a/src/components/VabUpload/index.vue
+++ b/src/components/VabUpload/index.vue
@@ -75,181 +75,181 @@
 </template>
 
 <script>
-  import { baseURL, tokenName } from '@/config'
+import { baseURL, tokenName } from "@/config";
 
-  export default {
-    name: 'VabUpload',
-    props: {
-      url: {
-        type: String,
-        default: '/upload',
-        required: true,
-      },
-      name: {
-        type: String,
-        default: 'file',
-        required: true,
-      },
-      limit: {
-        type: Number,
-        default: 50,
-        required: true,
-      },
-      size: {
-        type: Number,
-        default: 1,
-        required: true,
-      },
+export default {
+  name: "VabUpload",
+  props: {
+    url: {
+      type: String,
+      default: "/upload",
+      required: true,
     },
-    data() {
-      return {
-        show: false,
-        loading: false,
-        dialogVisible: false,
-        dialogImageUrl: '',
-        action: 'https://vab-unicloud-3a9da9.service.tcloudbase.com/upload',
-        headers: {},
-        fileList: [],
-        picture: 'picture',
-        imgNum: 0,
-        imgSuccessNum: 0,
-        imgErrorNum: 0,
-        typeList: null,
-        title: '涓婁紶',
-        dialogFormVisible: false,
-        data: {},
+    name: {
+      type: String,
+      default: "file",
+      required: true,
+    },
+    limit: {
+      type: Number,
+      default: 50,
+      required: true,
+    },
+    size: {
+      type: Number,
+      default: 1,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      show: false,
+      loading: false,
+      dialogVisible: false,
+      dialogImageUrl: "",
+      action: "https://vab-unicloud-3a9da9.service.tcloudbase.com/upload",
+      headers: {},
+      fileList: [],
+      picture: "picture",
+      imgNum: 0,
+      imgSuccessNum: 0,
+      imgErrorNum: 0,
+      typeList: null,
+      title: "涓婁紶",
+      dialogFormVisible: false,
+      data: {},
+    };
+  },
+  computed: {
+    percentage() {
+      if (this.allImgNum == 0) return 0;
+      return this.$baseLodash.round(this.imgNum / this.allImgNum, 2) * 100;
+    },
+  },
+  methods: {
+    submitUpload() {
+      this.$refs.upload.submit();
+    },
+    handleProgress(event, file, fileList) {
+      this.loading = true;
+      this.show = true;
+    },
+    handleChange(file, fileList) {
+      if (file.size > 1048576 * this.size) {
+        fileList.map((item, index) => {
+          if (item === file) {
+            fileList.splice(index, 1);
+          }
+        });
+        this.fileList = fileList;
+      } else {
+        this.allImgNum = fileList.length;
       }
     },
-    computed: {
-      percentage() {
-        if (this.allImgNum == 0) return 0
-        return this.$baseLodash.round(this.imgNum / this.allImgNum, 2) * 100
-      },
-    },
-    methods: {
-      submitUpload() {
-        this.$refs.upload.submit()
-      },
-      handleProgress(event, file, fileList) {
-        this.loading = true
-        this.show = true
-      },
-      handleChange(file, fileList) {
-        if (file.size > 1048576 * this.size) {
-          fileList.map((item, index) => {
-            if (item === file) {
-              fileList.splice(index, 1)
-            }
-          })
-          this.fileList = fileList
-        } else {
-          this.allImgNum = fileList.length
-        }
-      },
-      handleSuccess(response, file, fileList) {
-        this.imgNum = this.imgNum + 1
-        this.imgSuccessNum = this.imgSuccessNum + 1
-        if (fileList.length === this.imgNum) {
-          setTimeout(() => {
-            this.$baseMessage(
-              `涓婁紶瀹屾垚! 鍏变笂浼�${fileList.length}寮犲浘鐗嘸,
-              'success'
-            )
-          }, 1000)
-        }
+    handleSuccess(response, file, fileList) {
+      this.imgNum = this.imgNum + 1;
+      this.imgSuccessNum = this.imgSuccessNum + 1;
+      if (fileList.length === this.imgNum) {
+        setTimeout(() => {
+          this.$baseMessage(
+            `涓婁紶瀹屾垚! 鍏变笂浼�${fileList.length}寮犲浘鐗嘸,
+            "success"
+          );
+        }, 1000);
+      }
 
-        setTimeout(() => {
-          this.loading = false
-          this.show = false
-        }, 1000)
-      },
-      handleError(err, file, fileList) {
-        this.imgNum = this.imgNum + 1
-        this.imgErrorNum = this.imgErrorNum + 1
-        this.$baseMessage(
-          `鏂囦欢[${file.raw.name}]涓婁紶澶辫触,鏂囦欢澶у皬涓�${this.$baseLodash.round(
-            file.raw.size / 1024,
-            0
-          )}KB`,
-          'error'
-        )
-        setTimeout(() => {
-          this.loading = false
-          this.show = false
-        }, 1000)
-      },
-      handleRemove(file, fileList) {
-        this.imgNum = this.imgNum - 1
-        this.allNum = this.allNum - 1
-      },
-      handlePreview(file) {
-        this.dialogImageUrl = file.url
-        this.dialogVisible = true
-      },
-      handleExceed(files, fileList) {
-        this.$baseMessage(
-          `褰撳墠闄愬埗閫夋嫨 ${this.limit} 涓枃浠讹紝鏈閫夋嫨浜�
+      setTimeout(() => {
+        this.loading = false;
+        this.show = false;
+      }, 1000);
+    },
+    handleError(err, file, fileList) {
+      this.imgNum = this.imgNum + 1;
+      this.imgErrorNum = this.imgErrorNum + 1;
+      this.$baseMessage(
+        `鏂囦欢[${file.raw.name}]涓婁紶澶辫触,鏂囦欢澶у皬涓�${this.$baseLodash.round(
+          file.raw.size / 1024,
+          0
+        )}KB`,
+        "error"
+      );
+      setTimeout(() => {
+        this.loading = false;
+        this.show = false;
+      }, 1000);
+    },
+    handleRemove(file, fileList) {
+      this.imgNum = this.imgNum - 1;
+      this.allNum = this.allNum - 1;
+    },
+    handlePreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    handleExceed(files, fileList) {
+      this.$baseMessage(
+        `褰撳墠闄愬埗閫夋嫨 ${this.limit} 涓枃浠讹紝鏈閫夋嫨浜�
              ${files.length}
              涓枃浠禶,
-          'error'
-        )
-      },
-      handleShow(data) {
-        this.title = '涓婁紶'
-        this.data = data
-        this.dialogFormVisible = true
-      },
-      handleClose() {
-        this.fileList = []
-        this.picture = 'picture'
-        this.allImgNum = 0
-        this.imgNum = 0
-        this.imgSuccessNum = 0
-        this.imgErrorNum = 0
-        /* if ("development" === process.env.NODE_ENV) {
+        "error"
+      );
+    },
+    handleShow(data) {
+      this.title = "涓婁紶";
+      this.data = data;
+      this.dialogFormVisible = true;
+    },
+    handleClose() {
+      this.fileList = [];
+      this.picture = "picture";
+      this.allImgNum = 0;
+      this.imgNum = 0;
+      this.imgSuccessNum = 0;
+      this.imgErrorNum = 0;
+      /* if ("development" === process.env.NODE_ENV) {
           this.api = process.env.VUE_APP_BASE_API;
         } else {
           this.api = `${window.location.protocol}//${window.location.host}`;
         }
 
         this.action = this.api + this.url; */
-        this.dialogFormVisible = false
-      },
+      this.dialogFormVisible = false;
     },
-  }
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .upload {
-    height: 500px;
+.upload {
+  height: 500px;
 
-    .upload-content {
-      .el-upload__tip {
-        display: block;
-        height: 30px;
-        line-height: 30px;
+  .upload-content {
+    .el-upload__tip {
+      display: block;
+      height: 30px;
+      line-height: 30px;
+    }
+
+    ::v-deep {
+      .el-upload--picture-card {
+        width: 128px;
+        height: 128px;
+        margin: 3px 8px 8px 8px;
+        border: 2px dashed #c0ccda;
       }
 
-      ::v-deep {
-        .el-upload--picture-card {
+      .el-upload-list--picture {
+        margin-bottom: 20px;
+      }
+
+      .el-upload-list--picture-card {
+        .el-upload-list__item {
           width: 128px;
           height: 128px;
           margin: 3px 8px 8px 8px;
-          border: 2px dashed #c0ccda;
-        }
-
-        .el-upload-list--picture {
-          margin-bottom: 20px;
-        }
-
-        .el-upload-list--picture-card {
-          .el-upload-list__item {
-            width: 128px;
-            height: 128px;
-            margin: 3px 8px 8px 8px;
-          }
         }
       }
     }
   }
+}
 </style>
diff --git a/src/config/net.config.js b/src/config/net.config.js
index 6f2492d..170b755 100644
--- a/src/config/net.config.js
+++ b/src/config/net.config.js
@@ -4,20 +4,20 @@
 const network = {
   // 榛樿鐨勬帴鍙e湴鍧� 濡傛灉鏄紑鍙戠幆澧冨拰鐢熶骇鐜璧皏ab-mock-server锛屽綋鐒朵綘涔熷彲浠ラ�夋嫨鑷繁閰嶇疆鎴愰渶瑕佺殑鎺ュ彛鍦板潃
   baseURL:
-    process.env.NODE_ENV === 'development'
-      ? 'http://192.168.20.10:9696/api/v1/'
-      : 'http://192.168.20.10:9696/api/v1/',
+    process.env.NODE_ENV === "development"
+      ? "http://192.168.20.189:9696/api/v1/"
+      : "http://192.168.20.189:9696/api/v1/",
   //閰嶅悗绔暟鎹殑鎺ユ敹鏂瑰紡application/json;charset=UTF-8鎴栬�卆pplication/x-www-form-urlencoded;charset=UTF-8
-  contentType: 'application/json;charset=UTF-8',
+  contentType: "application/json;charset=UTF-8",
   //娑堟伅妗嗘秷澶辨椂闂�
   messageDuration: 3000,
   //鏈�闀胯姹傛椂闂�
   requestTimeout: 5000,
   //鎿嶄綔姝e父code锛屾敮鎸丼tring銆丄rray銆乮nt澶氱绫诲瀷
-  successCode: [200, 0],
+  successCode: [200, 204, 0],
   //鐧诲綍澶辨晥code
   invalidCode: 402,
   //鏃犳潈闄恈ode
   noPermissionCode: 401,
-}
-module.exports = network
+};
+module.exports = network;
diff --git a/src/config/permission.js b/src/config/permission.js
index ce86eb5..a57fe21 100644
--- a/src/config/permission.js
+++ b/src/config/permission.js
@@ -2,83 +2,86 @@
  * @author chuzhixin 1204505056@qq.com 锛堜笉鎯充繚鐣檃uthor鍙垹闄わ級
  * @description 璺敱瀹堝崼锛岀洰鍓嶄袱绉嶆ā寮忥細all妯″紡涓巌ntelligence妯″紡
  */
-import router from '@/router'
-import store from '@/store'
-import VabProgress from 'nprogress'
-import 'nprogress/nprogress.css'
-import getPageTitle from '@/utils/pageTitle'
+import router from "@/router";
+import store from "@/store";
+import VabProgress from "nprogress";
+import "nprogress/nprogress.css";
+import getPageTitle from "@/utils/pageTitle";
 import {
   authentication,
   loginInterception,
   progressBar,
   recordRoute,
   routesWhiteList,
-} from '@/config'
+} from "@/config";
 
 VabProgress.configure({
-  easing: 'ease',
+  easing: "ease",
   speed: 500,
   trickleSpeed: 200,
   showSpinner: false,
-})
+});
 router.beforeResolve(async (to, from, next) => {
-  if (progressBar) VabProgress.start()
-  let hasToken = store.getters['user/accessToken']
+  if (progressBar) VabProgress.start();
+  let hasToken = store.getters["user/accessToken"];
 
-  if (!loginInterception) hasToken = true
+  if (!loginInterception) hasToken = true;
 
   if (hasToken) {
-    if (to.path === '/login') {
-      next({ path: '/' })
-      if (progressBar) VabProgress.done()
+    if (to.path === "/login") {
+      next({ path: "/" });
+      if (progressBar) VabProgress.done();
     } else {
       const hasPermissions =
-        store.getters['user/permissions'] &&
-        store.getters['user/permissions'].length > 0
+        store.getters["user/permissions"] &&
+        store.getters["user/permissions"].length > 0;
       if (hasPermissions) {
-        next()
+        next();
       } else {
         try {
-          let permissions
+          let permissions;
           if (!loginInterception) {
             //settings.js loginInterception涓篺alse鏃讹紝鍒涘缓铏氭嫙鏉冮檺
-            await store.dispatch('user/setPermissions', ['admin'])
-            permissions = ['admin']
+            await store.dispatch("user/setPermissions", ["admin"]);
+            permissions = ["admin"];
           } else {
-            permissions = await store.dispatch('user/getUserInfo')
+            permissions = await store.dispatch("user/getUserInfo");
           }
 
-          let accessRoutes = []
-          if (authentication === 'intelligence') {
-            accessRoutes = await store.dispatch('routes/setRoutes', permissions)
-          } else if (authentication === 'all') {
-            accessRoutes = await store.dispatch('routes/setAllRoutes')
+          let accessRoutes = [];
+          if (authentication === "intelligence") {
+            accessRoutes = await store.dispatch(
+              "routes/setRoutes",
+              permissions
+            );
+          } else if (authentication === "all") {
+            accessRoutes = await store.dispatch("routes/setAllRoutes");
           }
           accessRoutes.forEach((item) => {
-            router.addRoute(item)
-          })
-          next({ ...to, replace: true })
+            router.addRoute(item);
+          });
+          next({ ...to, replace: true });
         } catch {
-          await store.dispatch('user/resetAccessToken')
-          if (progressBar) VabProgress.done()
+          await store.dispatch("user/resetAccessToken");
+          if (progressBar) VabProgress.done();
         }
       }
     }
   } else {
     if (routesWhiteList.indexOf(to.path) !== -1) {
-      next()
+      next();
     } else {
       if (recordRoute) {
-        next(`/login?redirect=${to.path}`)
+        next(`/login?redirect=${to.path}`);
       } else {
-        next('/login')
+        next("/login");
       }
 
-      if (progressBar) VabProgress.done()
+      if (progressBar) VabProgress.done();
     }
   }
-  document.title = getPageTitle(to.meta.title)
-})
+  document.title = getPageTitle(to.meta.title);
+});
 router.afterEach(() => {
-  if (progressBar) VabProgress.done()
-})
+  if (progressBar) VabProgress.done();
+});
diff --git a/src/config/setting.config.js b/src/config/setting.config.js
index c448c86..bfc3840 100644
--- a/src/config/setting.config.js
+++ b/src/config/setting.config.js
@@ -3,25 +3,25 @@
  */
 const setting = {
   // 寮�鍙戜互鍙婇儴缃叉椂鐨刄RL
-  publicPath: '',
+  publicPath: "",
   // 鐢熶骇鐜鏋勫缓鏂囦欢鐨勭洰褰曞悕
-  outputDir: 'dist',
+  outputDir: "dist",
   // 鏀剧疆鐢熸垚鐨勯潤鎬佽祫婧� (js銆乧ss銆乮mg銆乫onts) 鐨� (鐩稿浜� outputDir 鐨�) 鐩綍銆�
-  assetsDir: 'static',
+  assetsDir: "static",
   // 寮�鍙戠幆澧冩瘡娆′繚瀛樻椂鏄惁杈撳嚭涓篹slint缂栬瘧璀﹀憡
   lintOnSave: false,
   // 杩涜缂栬瘧鐨勪緷璧�
   transpileDependencies: [],
   //鏍囬 锛堝寘鎷垵娆″姞杞介洩鑺卞睆鐨勬爣棰� 椤甸潰鐨勬爣棰� 娴忚鍣ㄧ殑鏍囬锛�
-  title: 'Basic鑷姩鏋勫缓绯荤粺',
+  title: "Basic鑷姩鏋勫缓绯荤粺",
   //绠�鍐�
-  abbreviation: 'vab',
+  abbreviation: "vab",
   //寮�鍙戠幆澧冪鍙e彿
-  devPort: '81',
+  devPort: "81",
   //鐗堟湰鍙�
   version: process.env.VUE_APP_VERSION,
   //杩欎竴椤归潪甯搁噸瑕侊紒璇峰姟蹇呬繚鐣橫IT鍗忚涓媝ackage.json鍙奵opyright浣滆�呬俊鎭� 鍗冲彲鍏嶈垂鍟嗙敤锛屼笉閬靛畧姝ら」绾﹀畾浣犲皢鏃犳硶浣跨敤璇ユ鏋讹紝濡傞渶鑷畾涔夌増鏉冧俊鎭鑱旂郴QQ1204505056
-  copyright: 'vab',
+  copyright: "vab",
   //鏄惁鏄剧ず椤甸潰搴曢儴鑷畾涔夌増鏉冧俊鎭�
   footerCopyright: true,
   //鏄惁鏄剧ず椤堕儴杩涘害鏉�
@@ -29,42 +29,42 @@
   //缂撳瓨璺敱鐨勬渶澶ф暟閲�
   keepAliveMaxNum: 99,
   // 璺敱妯″紡锛屽彲閫夊�间负 history 鎴� hash
-  routerMode: 'hash',
+  routerMode: "hash",
   //涓嶇粡杩噒oken鏍¢獙鐨勮矾鐢�
-  routesWhiteList: ['/login', '/register', '/404', '/401'],
+  routesWhiteList: ["/login", "/register", "/404", "/401"],
   //鍔犺浇鏃舵樉绀烘枃瀛�
-  loadingText: '姝e湪鍔犺浇涓�...',
+  loadingText: "姝e湪鍔犺浇涓�...",
   //token鍚嶇О
-  tokenName: 'accessToken',
+  tokenName: "access_token",
   //token鍦╨ocalStorage銆乻essionStorage瀛樺偍鐨刱ey鐨勫悕绉�
-  tokenTableName: 'vue-admin-beautiful-2021',
+  tokenTableName: "va-integrate",
   //token瀛樺偍浣嶇疆localStorage sessionStorage
-  storage: 'localStorage',
+  storage: "localStorage",
   //token澶辨晥鍥為��鍒扮櫥褰曢〉鏃舵槸鍚﹁褰曟湰娆$殑璺敱
   recordRoute: true,
   //鏄惁鏄剧ずlogo锛屼笉鏄剧ず鏃惰缃甪alse锛屾樉绀烘椂璇峰~鍐檙emixIcon鍥炬爣鍚嶇О锛屾殏鏃跺彧鏀寔璁剧疆remixIcon
-  logo: 'vuejs-fill',
+  logo: "vuejs-fill",
   //鏄惁鏄剧ず鍦ㄩ〉闈㈤珮浜敊璇�
-  errorLog: ['development', 'production'],
+  errorLog: ["development", "production"],
   //鏄惁寮�鍚櫥褰曟嫤鎴�
   loginInterception: true,
   //鏄惁寮�鍚櫥褰昍SA鍔犲瘑
   loginRSA: true,
   //intelligence鍜宎ll涓ょ鏂瑰紡锛屽墠鑰呭悗绔潈闄愬彧鎺у埗permissions涓嶆帶鍒秜iew鏂囦欢鐨刬mport锛堝墠鍚庣閰嶅悎锛屽噺杞诲悗绔伐浣滈噺锛夛紝all鏂瑰紡瀹屽叏浜ょ粰鍚庣鍓嶇鍙礋璐e姞杞�
-  authentication: 'intelligence',
+  authentication: "intelligence",
   //vertical甯冨眬鏃舵槸鍚﹀彧淇濇寔涓�涓瓙鑿滃崟鐨勫睍寮�
   uniqueOpened: true,
   //vertical甯冨眬鏃堕粯璁ゅ睍寮�鐨勮彍鍗昿ath锛屼娇鐢ㄩ�楀彿闅斿紑寤鸿鍙睍寮�涓�涓�
-  defaultOopeneds: ['/vab'],
+  defaultOopeneds: ["/vab"],
   //闇�瑕佸姞loading灞傜殑璇锋眰锛岄槻姝㈤噸澶嶆彁浜�
-  debounce: ['doEdit'],
+  debounce: ["doEdit"],
   //闇�瑕佽嚜鍔ㄦ敞鍏ュ苟鍔犺浇鐨勬ā鍧�
-  providePlugin: { maptalks: 'maptalks', 'window.maptalks': 'maptalks' },
+  providePlugin: { maptalks: "maptalks", "window.maptalks": "maptalks" },
   //npm run build鏃舵槸鍚﹁嚜鍔ㄧ敓鎴�7z鍘嬬缉鍖�
   build7z: false,
   //浠g爜鐢熸垚鏈虹敓鎴愬湪view涓嬬殑鏂囦欢澶瑰悕绉�
-  templateFolder: 'project',
+  templateFolder: "project",
   //鏄惁鏄剧ず缁堢donation鎵撳嵃
   donation: false,
-}
-module.exports = setting
+};
+module.exports = setting;
diff --git a/src/layouts/components/VabAvatar/index.vue b/src/layouts/components/VabAvatar/index.vue
index 6ee4913..2f5edc8 100644
--- a/src/layouts/components/VabAvatar/index.vue
+++ b/src/layouts/components/VabAvatar/index.vue
@@ -10,51 +10,159 @@
     </span>
 
     <el-dropdown-menu slot="dropdown">
+      <el-dropdown-item command="password" divided>淇敼瀵嗙爜</el-dropdown-item>
       <el-dropdown-item command="logout" divided>閫�鍑虹櫥褰�</el-dropdown-item>
     </el-dropdown-menu>
+
+    <el-dialog
+      title="淇敼瀵嗙爜"
+      :visible.sync="dialogVisible"
+      width="25%"
+      :modal="false"
+      :close-on-click-modal="false"
+      destroy-on-close
+    >
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="鍘熷瘑鐮�" prop="oldPassword">
+          <el-input
+            v-model.trim="form.oldPassword"
+            autocomplete="off"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="鏂板瘑鐮�" prop="newPassword">
+          <el-input
+            v-model.trim="form.newPassword"
+            autocomplete="off"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="纭瀵嗙爜" prop="confirmPassword">
+          <el-input
+            v-model.trim="form.confirmPassword"
+            autocomplete="off"
+            show-password
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="resetPassword">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
   </el-dropdown>
 </template>
 
 <script>
-import { mapGetters } from 'vuex'
-import { recordRoute } from '@/config'
+import { mapGetters } from "vuex";
+import { recordRoute } from "@/config";
+import { updatePassword } from "@/api/user";
 
 export default {
-  name: 'VabAvatar',
+  name: "VabAvatar",
+  data() {
+    var validatePass = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("璇峰啀娆¤緭鍏ュ瘑鐮�"));
+      } else if (value.length < 6) {
+        callback(new Error("璇疯緭鍏�6浣嶄互涓婂瘑鐮�"));
+      } else {
+        callback();
+      }
+    };
+
+    var validatePass2 = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("璇峰啀娆¤緭鍏ュ瘑鐮�"));
+      } else if (value !== this.form.newPassword) {
+        callback(new Error("涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�!"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      form: {},
+      rules: {
+        oldPassword: [
+          {
+            required: true,
+            trigger: "blur",
+            message: "鍘熷瘑鐮佷笉鑳戒负绌�",
+          },
+        ],
+        newPassword: [
+          {
+            validator: validatePass,
+            required: true,
+            trigger: "blur",
+          },
+        ],
+        confirmPassword: [
+          {
+            validator: validatePass2,
+            required: true,
+            trigger: "blur",
+          },
+        ],
+      },
+      dialogVisible: false,
+    };
+  },
   computed: {
     ...mapGetters({
-      avatar: 'user/avatar',
-      username: 'user/username',
+      avatar: "user/avatar",
+      username: "user/username",
+      userId: "user/userId",
     }),
   },
   methods: {
     handleCommand(command) {
       switch (command) {
-        case 'logout':
-          this.logout()
-          break
+        case "logout":
+          this.logout();
+          break;
+        case "password":
+          this.dialogVisible = true;
+          this.form = {};
+          break;
       }
-    },
-    personalCenter() {
-      this.$router.push('/personalCenter/personalCenter')
     },
     logout() {
       this.$baseConfirm(
-        '鎮ㄧ‘瀹氳閫�鍑�' + this.$baseTitle + '鍚�?',
+        "鎮ㄧ‘瀹氳閫�鍑�" + this.$baseTitle + "鍚�?",
         null,
         async () => {
-          await this.$store.dispatch('user/logout')
+          await this.$store.dispatch("user/logout");
           if (recordRoute) {
-            const fullPath = this.$route.fullPath
-            this.$router.push(`/login?redirect=${fullPath}`)
+            const fullPath = this.$route.fullPath;
+            this.$router.push(`/login?redirect=${fullPath}`);
           } else {
-            this.$router.push('/login')
+            this.$router.push("/login");
           }
         }
-      )
+      );
+    },
+    resetPassword() {
+      this.$refs["form"].validate(async (valid) => {
+        if (valid) {
+          let rsp = await updatePassword(this.userId, {
+            oldPassword: this.form.oldPassword,
+            newPassword: this.form.newPassword,
+          });
+          if (rsp && rsp.success) {
+            this.$baseMessage(rsp.msg, "success");
+            this.$refs["form"].resetFields();
+            this.dialogVisible = false;
+          }
+        }
+      });
+    },
+    handleClose() {
+      console.log("close");
+      this.$refs["form"].resetFields();
     },
   },
-}
+};
 </script>
 <style lang="scss" scoped>
 .avatar-dropdown {
diff --git a/src/layouts/components/VabNavBar/index.vue b/src/layouts/components/VabNavBar/index.vue
index 7b59b82..c6fb8f8 100644
--- a/src/layouts/components/VabNavBar/index.vue
+++ b/src/layouts/components/VabNavBar/index.vue
@@ -16,7 +16,12 @@
         <div class="right-panel">
           <vab-error-log />
           <vab-full-screen-bar @refresh="refreshRoute" />
-          <vab-icon title="閲嶈浇鎵�鏈夎矾鐢�" :pulse="pulse" :icon="['fas', 'redo']" @click="refreshRoute" />
+          <vab-icon
+            title="閲嶈浇鎵�鏈夎矾鐢�"
+            :pulse="pulse"
+            :icon="['fas', 'redo']"
+            @click="refreshRoute"
+          />
           <vab-avatar />
           <!--  <vab-icon
             title="閫�鍑虹郴缁�"
@@ -30,39 +35,39 @@
 </template>
 
 <script>
-import { mapActions, mapGetters } from 'vuex'
+import { mapActions, mapGetters } from "vuex";
 
 export default {
-  name: 'VabNavBar',
+  name: "VabNavBar",
   data() {
     return {
       pulse: false,
-    }
+    };
   },
   computed: {
     ...mapGetters({
-      collapse: 'settings/collapse',
-      visitedRoutes: 'tabsBar/visitedRoutes',
-      device: 'settings/device',
-      routes: 'routes/routes',
+      collapse: "settings/collapse",
+      visitedRoutes: "tabsBar/visitedRoutes",
+      device: "settings/device",
+      routes: "routes/routes",
     }),
   },
   methods: {
     ...mapActions({
-      changeCollapse: 'settings/changeCollapse',
+      changeCollapse: "settings/changeCollapse",
     }),
     handleCollapse() {
-      this.changeCollapse()
+      this.changeCollapse();
     },
     async refreshRoute() {
-      this.$baseEventBus.$emit('reload-router-view')
-      this.pulse = true
+      this.$baseEventBus.$emit("reload-router-view");
+      this.pulse = true;
       setTimeout(() => {
-        this.pulse = false
-      }, 1000)
+        this.pulse = false;
+      }, 1000);
     },
   },
-}
+};
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/plugins/echarts.js b/src/plugins/echarts.js
index f600f83..f07a15d 100644
--- a/src/plugins/echarts.js
+++ b/src/plugins/echarts.js
@@ -1,4 +1,4 @@
-import 'echarts'
-import VabChart from 'vue-echarts'
+import "echarts";
+import VabChart from "vue-echarts";
 
-export default VabChart
+export default VabChart;
diff --git a/src/plugins/element.js b/src/plugins/element.js
index 3b91ff0..41226f1 100644
--- a/src/plugins/element.js
+++ b/src/plugins/element.js
@@ -1,9 +1,9 @@
-import Vue from 'vue'
-import ElementUI from 'element-ui'
-import 'element-ui/lib/theme-chalk/display.css'
+import Vue from "vue";
+import ElementUI from "element-ui";
+import "element-ui/lib/theme-chalk/display.css";
 
-import '@/styles/element-variables.scss'
+import "@/styles/element-variables.scss";
 
 Vue.use(ElementUI, {
-  size: 'small',
-})
+  size: "small",
+});
diff --git a/src/plugins/index.js b/src/plugins/index.js
index 2d4322a..d56a1fc 100644
--- a/src/plugins/index.js
+++ b/src/plugins/index.js
@@ -1,17 +1,17 @@
 /* 鍏叡寮曞叆,鍕块殢鎰忎慨鏀�,淇敼鏃堕渶缁忚繃纭 */
-import Vue from 'vue'
-import './element'
-import './support'
-import '@/styles/vab.scss'
-import '@/remixIcon'
-import '@/colorfulIcon'
-import '@/config/permission'
-import '@/utils/errorLog'
-import './vabIcon'
-import VabPermissions from 'zx-layouts/Permissions'
-import Vab from '@/utils/vab'
-import VabCount from 'zx-count'
+import Vue from "vue";
+import "./element";
+import "./support";
+import "@/styles/vab.scss";
+import "@/remixIcon";
+import "@/colorfulIcon";
+import "@/config/permission";
+import "@/utils/errorLog";
+import "./vabIcon";
+import VabPermissions from "zx-layouts/Permissions";
+import Vab from "@/utils/vab";
+import VabCount from "zx-count";
 
-Vue.use(Vab)
-Vue.use(VabPermissions)
-Vue.use(VabCount)
+Vue.use(Vab);
+Vue.use(VabPermissions);
+Vue.use(VabCount);
diff --git a/src/router/index.js b/src/router/index.js
index bac4ddc..e8786b8 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,42 +1,42 @@
-import Vue from 'vue'
-import VueRouter from 'vue-router'
-import Layout from '@/layouts'
-import { publicPath, routerMode } from '@/config'
+import Vue from "vue";
+import VueRouter from "vue-router";
+import Layout from "@/layouts";
+import { publicPath, routerMode } from "@/config";
 
-Vue.use(VueRouter)
+Vue.use(VueRouter);
 export const constantRoutes = [
   {
-    path: '/login',
-    component: () => import('@/views/login/index'),
+    path: "/login",
+    component: () => import("@/views/login/index"),
     hidden: true,
   },
   {
-    path: '/401',
-    name: '401',
-    component: () => import('@/views/401'),
+    path: "/401",
+    name: "401",
+    component: () => import("@/views/401"),
     hidden: true,
   },
   {
-    path: '/404',
-    name: '404',
-    component: () => import('@/views/404'),
+    path: "/404",
+    name: "404",
+    component: () => import("@/views/404"),
     hidden: true,
   },
-]
+];
 
 export const asyncRoutes = [
   {
-    path: '/',
+    path: "/",
     component: Layout,
-    redirect: '/index',
+    redirect: "/index",
     children: [
       {
-        path: 'index',
-        name: 'Index',
-        component: () => import('@/views/index/index'),
+        path: "index",
+        name: "Index",
+        component: () => import("@/views/index/index"),
         meta: {
-          title: '棣栭〉',
-          icon: 'home',
+          title: "棣栭〉",
+          icon: "home",
           affix: true,
         },
       },
@@ -44,31 +44,52 @@
   },
 
   {
-    path: '/project',
+    path: "/project",
     component: Layout,
-    redirect: 'project',
+    redirect: "project",
     // name: 'Vab',
     // alwaysShow: true,
     children: [
       {
-        path: 'index',
-        component: () => import('@/views/project/index'),
-        name: 'Project',
+        path: "index",
+        component: () => import("@/views/project/index"),
+        name: "Project",
         meta: {
-          title: '椤圭洰',
-          icon: 'box-open',
-          permissions: ['admin'],
+          title: "椤圭洰",
+          icon: "box-open",
+          affix: true,
         },
       },
     ],
   },
 
   {
-    path: '*',
-    redirect: '/404',
+    path: "/user",
+    component: Layout,
+    redirect: "user",
+    // name: 'Vab',
+    // alwaysShow: true,
+    children: [
+      {
+        path: "index",
+        component: () => import("@/views/user/index"),
+        name: "User",
+        meta: {
+          title: "鐢ㄦ埛",
+          icon: "user",
+          permissions: ["admin"],
+        },
+      },
+    ],
+    meta: { permissions: ["admin"] },
+  },
+
+  {
+    path: "*",
+    redirect: "/404",
     hidden: true,
   },
-]
+];
 
 const router = new VueRouter({
   base: publicPath,
@@ -77,10 +98,10 @@
     y: 0,
   }),
   routes: constantRoutes,
-})
+});
 
 export function resetRouter() {
-  location.reload()
+  location.reload();
 }
 
-export default router
+export default router;
diff --git a/src/store/modules/routes.js b/src/store/modules/routes.js
index 916bcb1..0239891 100644
--- a/src/store/modules/routes.js
+++ b/src/store/modules/routes.js
@@ -2,41 +2,41 @@
  * @author chuzhixin 1204505056@qq.com 锛堜笉鎯充繚鐣檃uthor鍙垹闄わ級
  * @description 璺敱鎷︽埅鐘舵�佺鐞嗭紝鐩墠涓ょ妯″紡锛歛ll妯″紡涓巌ntelligence妯″紡锛屽叾涓璸artialRoutes鏄彍鍗曟殏鏈娇鐢�
  */
-import { asyncRoutes, constantRoutes } from '@/router'
-import { convertRouter, filterAsyncRoutes } from '@/utils/handleRoutes'
+import { asyncRoutes, constantRoutes } from "@/router";
+import { convertRouter, filterAsyncRoutes } from "@/utils/handleRoutes";
 
 const state = () => ({
   routes: [],
   partialRoutes: [],
-})
+});
 const getters = {
   routes: (state) => state.routes,
   partialRoutes: (state) => state.partialRoutes,
-}
+};
 const mutations = {
   setRoutes(state, routes) {
-    state.routes = constantRoutes.concat(routes)
+    state.routes = constantRoutes.concat(routes);
   },
   setAllRoutes(state, routes) {
     // state.routes = constantRoutes.concat(routes)
   },
   setPartialRoutes(state, routes) {
-    state.partialRoutes = constantRoutes.concat(routes)
+    state.partialRoutes = constantRoutes.concat(routes);
   },
-}
+};
 const actions = {
   async setRoutes({ commit }, permissions) {
     //寮�婧愮増鍙繃婊ゅ姩鎬佽矾鐢眕ermissions锛宎dmin涓嶅啀榛樿鎷ユ湁鍏ㄩ儴鏉冮檺
     const finallyAsyncRoutes = await filterAsyncRoutes(
       [...asyncRoutes],
       permissions
-    )
-    commit('setRoutes', finallyAsyncRoutes)
-    return finallyAsyncRoutes
+    );
+    commit("setRoutes", finallyAsyncRoutes);
+    return finallyAsyncRoutes;
   },
   setPartialRoutes({ commit }, accessRoutes) {
-    commit('setPartialRoutes', accessRoutes)
-    return accessRoutes
+    commit("setPartialRoutes", accessRoutes);
+    return accessRoutes;
   },
-}
-export default { state, getters, mutations, actions }
+};
+export default { state, getters, mutations, actions };
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 24d681e..abc79e2 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -3,97 +3,103 @@
  * @description 鐧诲綍銆佽幏鍙栫敤鎴蜂俊鎭�侀��鍑虹櫥褰曘�佹竻闄ccessToken閫昏緫锛屼笉寤鸿淇敼
  */
 
-import Vue from 'vue'
-import { getUserInfo, login, logout } from '@/api/user'
+import Vue from "vue";
+import { getUserInfo, login, logout } from "@/api/user";
 import {
   getAccessToken,
   removeAccessToken,
   setAccessToken,
-} from '@/utils/accessToken'
-import { resetRouter } from '@/router'
-import { title, tokenName } from '@/config'
+} from "@/utils/accessToken";
+import { resetRouter } from "@/router";
+import { title, tokenName } from "@/config";
 
 const state = () => ({
   accessToken: getAccessToken(),
-  username: '',
-  avatar: '',
+  username: "",
+  userId: "",
+  avatar: "",
   permissions: [],
-})
+});
 const getters = {
   accessToken: (state) => state.accessToken,
   username: (state) => state.username,
+  userId: (state) => state.userId,
   avatar: (state) => state.avatar,
   permissions: (state) => state.permissions,
-}
+};
 const mutations = {
   setAccessToken(state, accessToken) {
-    state.accessToken = accessToken
-    setAccessToken(accessToken)
+    state.accessToken = accessToken;
+    setAccessToken(accessToken);
   },
   setUsername(state, username) {
-    state.username = username
+    state.username = username;
+  },
+  setUserId(state, id) {
+    state.userId = id;
   },
   setAvatar(state, avatar) {
-    state.avatar = avatar
+    state.avatar = avatar;
   },
   setPermissions(state, permissions) {
-    state.permissions = permissions
+    state.permissions = permissions;
   },
-}
+};
 const actions = {
   setPermissions({ commit }, permissions) {
-    commit('setPermissions', permissions)
+    commit("setPermissions", permissions);
   },
   async login({ commit }, userInfo) {
-    const { data } = await login(userInfo)
-    const accessToken = data[tokenName]
+    const { data } = await login(userInfo);
+    const accessToken = data[tokenName];
     if (accessToken) {
-      commit('setAccessToken', accessToken)
-      const hour = new Date().getHours()
+      commit("setAccessToken", accessToken);
+      const hour = new Date().getHours();
       const thisTime =
         hour < 8
-          ? '鏃╀笂濂�'
+          ? "鏃╀笂濂�"
           : hour <= 11
-          ? '涓婂崍濂�'
+          ? "涓婂崍濂�"
           : hour <= 13
-          ? '涓崍濂�'
+          ? "涓崍濂�"
           : hour < 18
-          ? '涓嬪崍濂�'
-          : '鏅氫笂濂�'
-      Vue.prototype.$baseNotify(`娆㈣繋鐧诲綍${title}`, `${thisTime}锛乣)
+          ? "涓嬪崍濂�"
+          : "鏅氫笂濂�";
+      Vue.prototype.$baseNotify(`娆㈣繋鐧诲綍${title}`, `${thisTime}锛乣);
     } else {
       Vue.prototype.$baseMessage(
         `鐧诲綍鎺ュ彛寮傚父锛屾湭姝g‘杩斿洖${tokenName}...`,
-        'error'
-      )
+        "error"
+      );
     }
   },
   async getUserInfo({ commit, state }) {
-    const { data } = await getUserInfo(state.accessToken)
+    const { data } = await getUserInfo(state.accessToken);
     if (!data) {
-      Vue.prototype.$baseMessage('楠岃瘉澶辫触锛岃閲嶆柊鐧诲綍...', 'error')
-      return false
+      Vue.prototype.$baseMessage("楠岃瘉澶辫触锛岃閲嶆柊鐧诲綍...", "error");
+      return false;
     }
-    let { permissions, username, avatar } = data
+    let { permissions, username, userId, avatar } = data;
     if (permissions && username && Array.isArray(permissions)) {
-      commit('setPermissions', permissions)
-      commit('setUsername', username)
-      commit('setAvatar', avatar)
-      return permissions
+      commit("setPermissions", permissions);
+      commit("setUsername", username);
+      commit("setUserId", userId);
+      commit("setAvatar", avatar);
+      return permissions;
     } else {
-      Vue.prototype.$baseMessage('鐢ㄦ埛淇℃伅鎺ュ彛寮傚父', 'error')
-      return false
+      Vue.prototype.$baseMessage("鐢ㄦ埛淇℃伅鎺ュ彛寮傚父", "error");
+      return false;
     }
   },
   async logout({ dispatch }) {
-    await logout(state.accessToken)
-    await dispatch('resetAccessToken')
-    await resetRouter()
+    await logout(state.accessToken);
+    await dispatch("resetAccessToken");
+    await resetRouter();
   },
   resetAccessToken({ commit }) {
-    commit('setPermissions', [])
-    commit('setAccessToken', '')
-    removeAccessToken()
+    commit("setPermissions", []);
+    commit("setAccessToken", "");
+    removeAccessToken();
   },
-}
-export default { state, getters, mutations, actions }
+};
+export default { state, getters, mutations, actions };
diff --git a/src/utils/errorLog.js b/src/utils/errorLog.js
index 07a836c..6ab7ea0 100644
--- a/src/utils/errorLog.js
+++ b/src/utils/errorLog.js
@@ -1,25 +1,25 @@
-import Vue from 'vue'
-import store from '@/store'
-import { isArray, isString } from '@/utils/validate'
-import { errorLog } from '@/config'
+import Vue from "vue";
+import store from "@/store";
+import { isArray, isString } from "@/utils/validate";
+import { errorLog } from "@/config";
 
-const needErrorLog = errorLog
+const needErrorLog = errorLog;
 const checkNeed = () => {
-  const env = process.env.NODE_ENV
+  const env = process.env.NODE_ENV;
   if (isString(needErrorLog)) {
-    return env === needErrorLog
+    return env === needErrorLog;
   }
   if (isArray(needErrorLog)) {
-    return needErrorLog.includes(env)
+    return needErrorLog.includes(env);
   }
-  return false
-}
+  return false;
+};
 if (checkNeed()) {
   Vue.config.errorHandler = (err, vm, info) => {
-    console.error('vue-admin-beautiful閿欒鎷︽埅:', err, vm, info)
-    const url = window.location.href
+    console.error("vue-admin-beautiful閿欒鎷︽埅:", err, vm, info);
+    const url = window.location.href;
     Vue.nextTick(() => {
-      store.dispatch('errorLog/addErrorLog', { err, vm, info, url })
-    })
-  }
+      store.dispatch("errorLog/addErrorLog", { err, vm, info, url });
+    });
+  };
 }
diff --git a/src/utils/handleRoutes.js b/src/utils/handleRoutes.js
index c95ae92..62248c4 100644
--- a/src/utils/handleRoutes.js
+++ b/src/utils/handleRoutes.js
@@ -7,23 +7,23 @@
 export function convertRouter(asyncRoutes) {
   return asyncRoutes.map((route) => {
     if (route.component) {
-      if (route.component === 'Layout') {
-        route.component = (resolve) => require(['@/layouts'], resolve)
-      } else if (route.component === 'EmptyLayout') {
+      if (route.component === "Layout") {
+        route.component = (resolve) => require(["@/layouts"], resolve);
+      } else if (route.component === "EmptyLayout") {
         route.component = (resolve) =>
-          require(['@/layouts/EmptyLayout'], resolve)
+          require(["@/layouts/EmptyLayout"], resolve);
       } else {
-        const index = route.component.indexOf('views')
+        const index = route.component.indexOf("views");
         const path =
-          index > 0 ? route.component.slice(index) : `views/${route.component}`
-        route.component = (resolve) => require([`@/${path}`], resolve)
+          index > 0 ? route.component.slice(index) : `views/${route.component}`;
+        route.component = (resolve) => require([`@/${path}`], resolve);
       }
     }
     if (route.children && route.children.length)
-      route.children = convertRouter(route.children)
-    if (route.children && route.children.length === 0) delete route.children
-    return route
-  })
+      route.children = convertRouter(route.children);
+    if (route.children && route.children.length === 0) delete route.children;
+    return route;
+  });
 }
 
 /**
@@ -35,9 +35,9 @@
  */
 function hasPermission(permissions, route) {
   if (route.meta && route.meta.permissions) {
-    return permissions.some((role) => route.meta.permissions.includes(role))
+    return permissions.some((role) => route.meta.permissions.includes(role));
   } else {
-    return true
+    return true;
   }
 }
 
@@ -49,15 +49,15 @@
  * @returns {[]}
  */
 export function filterAsyncRoutes(routes, permissions) {
-  const finallyRoutes = []
+  const finallyRoutes = [];
   routes.forEach((route) => {
-    const item = { ...route }
+    const item = { ...route };
     if (hasPermission(permissions, item)) {
       if (item.children) {
-        item.children = filterAsyncRoutes(item.children, permissions)
+        item.children = filterAsyncRoutes(item.children, permissions);
       }
-      finallyRoutes.push(item)
+      finallyRoutes.push(item);
     }
-  })
-  return finallyRoutes
+  });
+  return finallyRoutes;
 }
diff --git a/src/utils/request.js b/src/utils/request.js
index 272a731..b06ceab 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -1,5 +1,5 @@
-import Vue from 'vue'
-import axios from 'axios'
+import Vue from "vue";
+import axios from "axios";
 import {
   baseURL,
   contentType,
@@ -10,116 +10,118 @@
   successCode,
   tokenName,
   loginInterception,
-} from '@/config'
-import store from '@/store'
-import qs from 'qs'
-import router from '@/router'
-import { isArray } from '@/utils/validate'
+} from "@/config";
+import store from "@/store";
+import qs from "qs";
+import router from "@/router";
+import { isArray } from "@/utils/validate";
 
-let loadingInstance
+let loadingInstance;
 
 /**
- * @author chuzhixin 1204505056@qq.com 锛堜笉鎯充繚鐣檃uthor鍙垹闄わ級
  * @description 澶勭悊code寮傚父
  * @param {*} code
  * @param {*} msg
  */
 const handleCode = (code, msg) => {
+  console.log(code, msg);
   switch (code) {
     case invalidCode:
-      Vue.prototype.$baseMessage(msg || `鍚庣鎺ュ彛${code}寮傚父`, 'error')
-      store.dispatch('user/resetAccessToken').catch(() => {})
+      Vue.prototype.$baseMessage(msg || `鍚庣鎺ュ彛${code}寮傚父`, "error");
+      store.dispatch("user/resetAccessToken").catch(() => {});
       if (loginInterception) {
-        location.reload()
+        location.reload();
       }
-      break
+      break;
     case noPermissionCode:
-      router.push({ path: '/401' }).catch(() => {})
-      break
+      router.push({ path: "/401" }).catch(() => {});
+      break;
     default:
-      Vue.prototype.$baseMessage(msg || `鍚庣鎺ュ彛${code}寮傚父`, 'error')
-      break
+      Vue.prototype.$baseMessage(msg || `鍚庣鎺ュ彛${code}寮傚父`, "error");
+      break;
   }
-}
+};
 
 const instance = axios.create({
   baseURL,
   timeout: requestTimeout,
   headers: {
-    'Content-Type': contentType,
+    "Content-Type": contentType,
   },
-})
+});
 
 instance.interceptors.request.use(
   (config) => {
-    if (store.getters['user/accessToken']) {
-      config.headers[tokenName] = store.getters['user/accessToken']
+    if (store.getters["user/accessToken"]) {
+      config.headers["Authorization"] =
+        "Bearer " + store.getters["user/accessToken"];
     }
     //杩欓噷浼氳繃婊ゆ墍鏈変负绌恒��0銆乫alse鐨刱ey锛屽鏋滀笉闇�瑕佽鑷娉ㄩ噴
     if (config.data)
       config.data = Vue.prototype.$baseLodash.pickBy(
         config.data,
         Vue.prototype.$baseLodash.identity
-      )
+      );
     if (
       config.data &&
-      config.headers['Content-Type'] ===
-        'application/x-www-form-urlencoded;charset=UTF-8'
+      config.headers["Content-Type"] ===
+        "application/x-www-form-urlencoded;charset=UTF-8"
     )
-      config.data = qs.stringify(config.data)
+      config.data = qs.stringify(config.data);
     if (debounce.some((item) => config.url.includes(item)))
-      loadingInstance = Vue.prototype.$baseLoading()
-    return config
+      loadingInstance = Vue.prototype.$baseLoading();
+    return config;
   },
   (error) => {
-    return Promise.reject(error)
+    return Promise.reject(error);
   }
-)
+);
 
 instance.interceptors.response.use(
   (response) => {
-    if (loadingInstance) loadingInstance.close()
+    if (loadingInstance) loadingInstance.close();
 
-    const { data, config } = response
-    const { code, msg } = data
+    const { data, config } = response;
+    const { code, msg } = data;
+
     // 鎿嶄綔姝e父Code鏁扮粍
     const codeVerificationArray = isArray(successCode)
       ? [...successCode]
-      : [...[successCode]]
+      : [...[successCode]];
     // 鏄惁鎿嶄綔姝e父
     if (codeVerificationArray.includes(code)) {
-      return data
+      return data;
     } else {
-      handleCode(code, msg)
+      handleCode(code, msg);
       return Promise.reject(
-        'vue-admin-beautiful璇锋眰寮傚父鎷︽埅:' +
-          JSON.stringify({ url: config.url, code, msg }) || 'Error'
-      )
+        "璇锋眰寮傚父鎷︽埅:" + JSON.stringify({ url: config.url, code, msg }) ||
+          "Error"
+      );
     }
   },
   (error) => {
-    if (loadingInstance) loadingInstance.close()
-    const { response, message } = error
+    if (loadingInstance) loadingInstance.close();
+    const { response, message } = error;
     if (error.response && error.response.data) {
-      const { status, data } = response
-      handleCode(status, data.msg || message)
-      return Promise.reject(error)
+      const { status, data } = response;
+      handleCode(status, data.msg || message);
+      return Promise.reject(error);
     } else {
-      let { message } = error
-      if (message === 'Network Error') {
-        message = '鍚庣鎺ュ彛杩炴帴寮傚父'
+      let { message } = error;
+      if (message === "Network Error") {
+        message = "鍚庣鎺ュ彛杩炴帴寮傚父";
       }
-      if (message.includes('timeout')) {
-        message = '鍚庣鎺ュ彛璇锋眰瓒呮椂'
+      if (message.includes("timeout")) {
+        message = "鍚庣鎺ュ彛璇锋眰瓒呮椂";
       }
-      if (message.includes('Request failed with status code')) {
-        const code = message.substr(message.length - 3)
-        message = '鍚庣鎺ュ彛' + code + '寮傚父'
+      if (message.includes("Request failed with status code")) {
+        const code = message.substr(message.length - 3);
+        message = "鍚庣鎺ュ彛" + code + "寮傚父";
       }
-      Vue.prototype.$baseMessage(message || `鍚庣鎺ュ彛鏈煡寮傚父`, 'error')
-      return Promise.reject(error)
+      Vue.prototype.$baseMessage(message || `鍚庣鎺ュ彛鏈煡寮傚父`, "error");
+      return Promise.reject(error);
     }
   }
-)
+);
 
-export default instance
+export default instance;
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 01100ed..bd15ad4 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -5,7 +5,7 @@
  * @returns {boolean}
  */
 export function isExternal(path) {
-  return /^(https?:|mailto:|tel:)/.test(path)
+  return /^(https?:|mailto:|tel:)/.test(path);
 }
 
 /**
@@ -15,7 +15,7 @@
  * @returns {boolean}
  */
 export function isPassword(str) {
-  return str.length >= 6
+  return str.length >= 5;
 }
 
 /**
@@ -25,8 +25,8 @@
  * @returns {boolean}
  */
 export function isNumber(value) {
-  const reg = /^[0-9]*$/
-  return reg.test(value)
+  const reg = /^[0-9]*$/;
+  return reg.test(value);
 }
 
 /**
@@ -36,8 +36,8 @@
  * @returns {boolean}
  */
 export function isName(value) {
-  const reg = /^[\u4e00-\u9fa5a-zA-Z0-9]+$/
-  return reg.test(value)
+  const reg = /^[\u4e00-\u9fa5a-zA-Z0-9]+$/;
+  return reg.test(value);
 }
 
 /**
@@ -48,8 +48,8 @@
  */
 export function isIP(ip) {
   const reg =
-    /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
-  return reg.test(ip)
+    /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
+  return reg.test(ip);
 }
 
 /**
@@ -60,8 +60,8 @@
  */
 export function isUrl(url) {
   const reg =
-    /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
-  return reg.test(url)
+    /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
+  return reg.test(url);
 }
 
 /**
@@ -71,8 +71,8 @@
  * @returns {boolean}
  */
 export function isLowerCase(str) {
-  const reg = /^[a-z]+$/
-  return reg.test(str)
+  const reg = /^[a-z]+$/;
+  return reg.test(str);
 }
 
 /**
@@ -82,8 +82,8 @@
  * @returns {boolean}
  */
 export function isUpperCase(str) {
-  const reg = /^[A-Z]+$/
-  return reg.test(str)
+  const reg = /^[A-Z]+$/;
+  return reg.test(str);
 }
 
 /**
@@ -93,8 +93,8 @@
  * @returns {boolean}
  */
 export function isAlphabets(str) {
-  const reg = /^[A-Za-z]+$/
-  return reg.test(str)
+  const reg = /^[A-Za-z]+$/;
+  return reg.test(str);
 }
 
 /**
@@ -104,7 +104,7 @@
  * @returns {boolean}
  */
 export function isString(str) {
-  return typeof str === 'string' || str instanceof String
+  return typeof str === "string" || str instanceof String;
 }
 
 /**
@@ -114,10 +114,10 @@
  * @returns {arg is any[]|boolean}
  */
 export function isArray(arg) {
-  if (typeof Array.isArray === 'undefined') {
-    return Object.prototype.toString.call(arg) === '[object Array]'
+  if (typeof Array.isArray === "undefined") {
+    return Object.prototype.toString.call(arg) === "[object Array]";
   }
-  return Array.isArray(arg)
+  return Array.isArray(arg);
 }
 
 /**
@@ -128,8 +128,8 @@
  */
 export function isPort(str) {
   const reg =
-    /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
-  return reg.test(str)
+    /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/;
+  return reg.test(str);
 }
 
 /**
@@ -139,8 +139,8 @@
  * @returns {boolean}
  */
 export function isPhone(str) {
-  const reg = /^1\d{10}$/
-  return reg.test(str)
+  const reg = /^1\d{10}$/;
+  return reg.test(str);
 }
 
 /**
@@ -151,8 +151,8 @@
  */
 export function isIdCard(str) {
   const reg =
-    /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
-  return reg.test(str)
+    /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
+  return reg.test(str);
 }
 
 /**
@@ -162,8 +162,8 @@
  * @returns {boolean}
  */
 export function isEmail(str) {
-  const reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
-  return reg.test(str)
+  const reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
+  return reg.test(str);
 }
 
 /**
@@ -173,8 +173,8 @@
  * @returns {boolean}
  */
 export function isChina(str) {
-  const reg = /^[\u4E00-\u9FA5]{2,4}$/
-  return reg.test(str)
+  const reg = /^[\u4E00-\u9FA5]{2,4}$/;
+  return reg.test(str);
 }
 
 /**
@@ -187,10 +187,10 @@
   return (
     str == null ||
     false ||
-    str === '' ||
-    str.trim() === '' ||
-    str.toLocaleLowerCase().trim() === 'null'
-  )
+    str === "" ||
+    str.trim() === "" ||
+    str.toLocaleLowerCase().trim() === "null"
+  );
 }
 
 /**
@@ -201,8 +201,8 @@
  */
 export function isTel(str) {
   const reg =
-    /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |杞�)*([0-9]{1,4}))?$/
-  return reg.test(str)
+    /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |杞�)*([0-9]{1,4}))?$/;
+  return reg.test(str);
 }
 
 /**
@@ -212,6 +212,6 @@
  * @returns {boolean}
  */
 export function isNum(str) {
-  const reg = /^\d+(\.\d{1,2})?$/
-  return reg.test(str)
+  const reg = /^\d+(\.\d{1,2})?$/;
+  return reg.test(str);
 }
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
index 33680f1..9839af0 100644
--- a/src/views/login/index.vue
+++ b/src/views/login/index.vue
@@ -1,11 +1,5 @@
 <template>
   <div class="login-container">
-    <el-alert
-      title="beautiful boys and girls娆㈣繋鍔犲叆vue-admin-beautifulQQ缇わ細972435319"
-      type="success"
-      :closable="false"
-      style="position: fixed"
-    ></el-alert>
     <el-row>
       <el-col :xs="24" :sm="24" :md="12" :lg="16" :xl="16">
         <div style="color: transparent">鍗犱綅绗�</div>
@@ -18,8 +12,7 @@
           class="login-form"
           label-position="left"
         >
-          <div class="title">hello !</div>
-          <div class="title-tips">娆㈣繋鏉ュ埌{{ title }}锛�</div>
+          <div class="title-tips">娆㈣繋浣跨敤{{ title }}锛�</div>
           <el-form-item style="margin-top: 40px" prop="username">
             <span class="svg-container svg-container-admin">
               <vab-icon :icon="['fas', 'user']" />
@@ -64,9 +57,6 @@
           >
             鐧诲綍
           </el-button>
-          <router-link to="/register">
-            <div style="margin-top: 20px">娉ㄥ唽</div>
-          </router-link>
         </el-form>
       </el-col>
     </el-row>
@@ -95,7 +85,7 @@
     };
     const validatePassword = (rule, value, callback) => {
       if (!isPassword(value)) {
-        callback(new Error("瀵嗙爜涓嶈兘灏戜簬6浣�"));
+        callback(new Error("瀵嗙爜涓嶈兘灏戜簬5浣�"));
       } else {
         callback();
       }
@@ -142,13 +132,6 @@
   beforeDestroy() {
     document.body.style.overflow = "auto";
   },
-  mounted() {
-    this.form.username = "admin";
-    this.form.password = "123456";
-    setTimeout(() => {
-      this.handleLogin();
-    }, 3000);
-  },
   methods: {
     handlePassword() {
       this.passwordType === "password"
@@ -170,7 +153,7 @@
                   ? "/"
                   : this.redirect;
               this.$router.push(routerPath).catch(() => {});
-              this.loading = false;
+              this.loading = true;
             })
             .catch(() => {
               this.loading = false;
diff --git a/src/views/project/components/ProjectEdit.vue b/src/views/project/components/ProjectEdit.vue
index 92a7ace..e613d8e 100644
--- a/src/views/project/components/ProjectEdit.vue
+++ b/src/views/project/components/ProjectEdit.vue
@@ -22,10 +22,13 @@
             <el-input
               v-model.trim="form.srcPassword"
               autocomplete="off"
-            ></el-input>
+              show-password
+            >
+              ></el-input
+            >
           </el-form-item>
           <el-form-item label="椤圭洰鎻忚堪" prop="desc">
-            <el-input v-model.trim="form.desc" autocomplete="off"></el-input>
+            <el-input v-model="form.desc" autocomplete="off"></el-input>
           </el-form-item>
           <el-form-item label="缂栬瘧鍒嗘敮" prop="branch">
             <el-input v-model.trim="form.branch" autocomplete="off"></el-input>
@@ -103,8 +106,10 @@
     save() {
       this.$refs["form"].validate(async (valid) => {
         if (valid) {
-          const { msg } = await doEdit(this.form);
-          this.$baseMessage(msg, "success");
+          const rsp = await doEdit(this.form);
+          if (rsp && rsp.success) {
+            this.$baseMessage(rsp.msg, "success");
+          }
           this.$refs["form"].resetFields();
           this.dialogFormVisible = false;
           this.$emit("fetch-data");
diff --git a/src/views/project/index.vue b/src/views/project/index.vue
index 6c2c5d8..3d4a639 100644
--- a/src/views/project/index.vue
+++ b/src/views/project/index.vue
@@ -68,16 +68,24 @@
 
             <el-table-column prop="state" width="150">
               <template #default="{ row }">
-                <el-tag>{{ packageState[row.state] }}</el-tag>
+                <el-tag :type="row.state == 0 ? 'success' : 'danger'">{{
+                  packageState[row.state]
+                }}</el-tag>
               </template>
             </el-table-column>
-            <el-table-column width="200">
+            <el-table-column width="300">
               <template #default="scope">
                 <el-button size="small" @click="handlePublish(scope.row)"
                   >鍙戝竷</el-button
                 >
                 <el-button size="small" @click="handleDownload(scope.row)"
                   >涓嬭浇</el-button
+                >
+                <el-button
+                  size="small"
+                  :disabled="scope.row.state === 0"
+                  @click="handleRebuild(scope.row)"
+                  >閲嶇疆</el-button
                 >
               </template>
             </el-table-column>
@@ -106,7 +114,9 @@
       <!-- <el-table-column show-overflow-tooltip label="褰撳墠鐗堟湰" prop="latestVersion"></el-table-column> -->
       <el-table-column label="鐘舵��">
         <template #default="{ row }">
-          <el-tag>{{ row.state | stateFilter }}</el-tag>
+          <el-tag :type="row.state == 2 ? 'danger' : 'success'">{{
+            row.state | stateFilter
+          }}</el-tag>
         </template>
       </el-table-column>
       <el-table-column
@@ -147,7 +157,7 @@
 
 <script>
 import { getList, deletePrj, getPkgList, buildPkg } from "@/api/project";
-import { publish, download } from "@/api/package";
+import { publish, download, rebuild } from "@/api/package";
 
 import TableEdit from "./components/ProjectEdit.vue";
 export default {
@@ -172,15 +182,14 @@
   },
   data() {
     return {
-      imgShow: true,
       list: [],
       listLoading: true,
       layout: "total, sizes, prev, pager, next, jumper",
       packageState: [
-        "瀹屾垚",
-        "宸叉彁浜�",
-        "鎺掗槦涓�",
-        "鎵撳寘涓�",
+        "鎵撳寘瀹屾垚",
+        "宸� 鎻� 浜�",
+        "鎺� 闃� 涓�",
+        "鎵� 鍖� 涓�",
         "缂栬瘧澶辫触",
         "鎵撳寘澶辫触",
       ],
@@ -277,7 +286,7 @@
       const { data, total } = await getPkgList(row.id);
       this.list.forEach((item, idx) => {
         if (item.id === row.id) {
-          this.list[idx].pkgList = data;
+          this.list[idx].pkgList = data.reverse();
         }
       });
     },
@@ -316,6 +325,15 @@
         }
       });
     },
+    handleRebuild(row) {
+      rebuild(row).then((rsp) => {
+        if (rsp && rsp.success) {
+          this.$baseMessage(rsp.msg, "success");
+        } else {
+          this.$baseMessage("淇濆瓨澶辫触", "error");
+        }
+      });
+    },
   },
 };
 </script>
diff --git a/src/views/user/components/UserEdit.vue b/src/views/user/components/UserEdit.vue
new file mode 100644
index 0000000..6367505
--- /dev/null
+++ b/src/views/user/components/UserEdit.vue
@@ -0,0 +1,116 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="dialogFormVisible"
+    width="500px"
+    :close-on-click-modal="false"
+    @close="close"
+  >
+    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+      <el-form-item label="鐢ㄦ埛鍚�" prop="username">
+        <el-tag v-if="!createAction">{{ form.username }}</el-tag>
+        <el-input
+          v-else
+          v-model.trim="form.username"
+          autocomplete="off"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="濮撳悕" prop="name">
+        <el-input v-model.trim="form.name" autocomplete="off"></el-input>
+      </el-form-item>
+      <el-form-item label="鎵嬫満鍙�" prop="tel">
+        <el-input v-model.trim="form.tel" autocomplete="off"></el-input>
+      </el-form-item>
+      <el-form-item label="鏉冮檺" prop="permissions">
+        <el-radio-group v-model="form.permissions">
+          <el-radio label="admin">绠$悊鍛�</el-radio>
+          <el-radio label="user">鐢ㄦ埛</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item v-if="createAction" label="瀵嗙爜" prop="tel">
+        <el-input v-model.trim="form.password" autocomplete="off"></el-input>
+      </el-form-item>
+    </el-form>
+
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="close">鍙� 娑�</el-button>
+      <el-button type="primary" @click="save">纭� 瀹�</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { doEdit, register } from "@/api/user";
+
+export default {
+  name: "UserEdit",
+  data() {
+    return {
+      activeName: "base",
+      form: {
+        name: "",
+        username: "",
+      },
+      rules: {
+        username: [
+          { required: true, trigger: "blur", message: "璇疯緭鍏ョ敤鎴峰悕" },
+        ],
+        password: [{ required: true, trigger: "blur", message: "璇疯緭鍏ュ瘑鐮�" }],
+      },
+      title: "",
+      dialogFormVisible: false,
+      createAction: false,
+    };
+  },
+  created() {},
+  methods: {
+    showEdit(row) {
+      if (!row) {
+        this.title = "娣诲姞";
+        this.createAction = true;
+        this.form.permissions = "user";
+      } else {
+        this.title = "缂栬緫";
+        this.form = Object.assign({}, row);
+        this.createAction = false;
+      }
+      this.dialogFormVisible = true;
+    },
+    close() {
+      this.$refs["form"].resetFields();
+      this.form = this.$options.data().form;
+      this.dialogFormVisible = false;
+      this.$emit("fetch-data");
+    },
+    async save() {
+      if (this.createAction) {
+        this.$refs["form"].validate(async (valid) => {
+          if (valid) {
+            let rsp = await register(this.form);
+            if (rsp && rsp.success) {
+              console.log(rsp);
+              this.$baseMessage(rsp.msg, "success");
+              this.closeDialog();
+            }
+          }
+        });
+      } else {
+        let rsp = await doEdit(this.form);
+        if (rsp && rsp.success) {
+          this.$baseMessage(rsp.msg, "success");
+          this.closeDialog();
+        }
+      }
+    },
+    closeDialog() {
+      this.$refs["form"].resetFields();
+      this.dialogFormVisible = false;
+      this.$emit("fetch-data");
+      this.form = this.$options.data().form;
+    },
+    handleClick(tab, event) {
+      // console.log(tab, event)
+    },
+  },
+};
+</script>
diff --git a/src/views/user/index.vue b/src/views/user/index.vue
new file mode 100644
index 0000000..4b38cd0
--- /dev/null
+++ b/src/views/user/index.vue
@@ -0,0 +1,254 @@
+<template>
+  <div class="table-container">
+    <vab-query-form>
+      <vab-query-form-left-panel>
+        <el-form
+          ref="form"
+          :model="queryForm"
+          :inline="true"
+          @submit.native.prevent
+        >
+          <el-form-item>
+            <el-input
+              v-model="queryForm.name"
+              placeholder="濮撳悕/鐢ㄦ埛鍚�/鎵嬫満鍙�"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button
+              icon="el-icon-search"
+              type="primary"
+              native-type="submit"
+              @click="handleQuery"
+              >鏌ヨ</el-button
+            >
+          </el-form-item>
+        </el-form>
+      </vab-query-form-left-panel>
+      <vab-query-form-right-panel>
+        <el-button icon="el-icon-plus" type="primary" @click="handleAdd">
+          娣诲姞</el-button
+        >
+        <el-button icon="el-icon-delete" type="danger" @click="handleDelete"
+          >鍒犻櫎</el-button
+        >
+      </vab-query-form-right-panel>
+    </vab-query-form>
+
+    <el-table
+      ref="tableSort"
+      v-loading="listLoading"
+      stripe
+      :data="list"
+      :element-loading-text="elementLoadingText"
+      :height="height"
+      @selection-change="setSelectRows"
+    >
+      <!-- <el-table-column show-overflow-tooltip type="selection" width="55"></el-table-column> -->
+      <el-table-column show-overflow-tooltip label="搴忓彿" width="95">
+        <template #default="scope">{{ scope.$index + 1 }}</template>
+      </el-table-column>
+      <el-table-column
+        show-overflow-tooltip
+        prop="username"
+        label="鐢ㄦ埛鍚�"
+      ></el-table-column>
+      <el-table-column
+        show-overflow-tooltip
+        prop="name"
+        label="濮撳悕"
+      ></el-table-column>
+      <el-table-column prop="tel" label="鎵嬫満鍙�"> </el-table-column>
+      <el-table-column label="鏉冮檺">
+        <template #default="{ row }">
+          <el-tag :type="row.permissions == 'admin' ? 'danger' : 'success'">{{
+            row.permissions
+          }}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="鍒涘缓鏃堕棿"
+        prop="createdAt"
+        width="200"
+      ></el-table-column>
+      <el-table-column label="鎿嶄綔" width="180px">
+        <template #default="{ row }">
+          <el-button type="text" @click="handleEdit(row)">缂栬緫</el-button>
+          <el-button
+            type="text"
+            style="color: red"
+            @click="handleDeleteRow(row)"
+            >鍒犻櫎</el-button
+          >
+          <el-button type="text" @click="resetPassword(row)"
+            >閲嶇疆瀵嗙爜</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+      :background="background"
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange"
+    ></el-pagination>
+    <table-edit ref="edit" @fetch-data="fetchData"></table-edit>
+  </div>
+</template>
+
+<script>
+import { getUsers, deleteUser, updatePassword } from "@/api/user";
+
+import TableEdit from "./components/UserEdit.vue";
+export default {
+  name: "ComprehensiveTable",
+  components: {
+    TableEdit,
+  },
+  data() {
+    return {
+      list: [],
+      listLoading: true,
+      layout: "total, sizes, prev, pager, next, jumper",
+
+      total: 0,
+      background: true,
+      selectRows: "",
+      elementLoadingText: "姝e湪鍔犺浇...",
+      queryForm: {
+        pageNo: 1,
+        pageSize: 20,
+        name: "",
+      },
+    };
+  },
+  computed: {
+    height() {
+      return this.$baseTableHeight();
+    },
+  },
+  mounted() {
+    this.fetchData();
+  },
+  methods: {
+    setSelectRows(val) {
+      this.selectRows = val;
+    },
+    handleAdd() {
+      this.$refs["edit"].showEdit();
+    },
+    handleEdit(row) {
+      this.$refs["edit"].showEdit(row);
+    },
+    handleDelete(row) {
+      if (this.selectRows.length > 0) {
+        const ids = this.selectRows.map((item) => item.id).join();
+        this.$baseConfirm("浣犵‘瀹氳鍒犻櫎閫変腑椤瑰悧", null, async () => {
+          const { msg } = await doDelete({ ids: ids });
+          this.$baseMessage(msg, "success");
+          this.fetchData();
+        });
+      } else {
+        this.$baseMessage("鏈�変腑浠讳綍琛�", "error");
+        return false;
+      }
+    },
+    handleDeleteRow(row) {
+      if (row.id) {
+        this.$baseConfirm("浣犵‘瀹氳鍒犻櫎褰撳墠椤瑰悧", null, async () => {
+          const { msg } = await deleteUser(row.id);
+          this.$baseMessage(msg, "success");
+          this.fetchData();
+        });
+      }
+    },
+    handleSizeChange(val) {
+      this.queryForm.pageSize = val;
+      this.fetchData();
+    },
+    handleCurrentChange(val) {
+      this.queryForm.pageNo = val;
+      this.fetchData();
+    },
+    handleQuery() {
+      this.queryForm.pageNo = 1;
+      this.fetchData();
+    },
+    async fetchData() {
+      this.listLoading = true;
+      this.list = [];
+      const { data, total } = await getUsers(this.queryForm);
+
+      if (data) {
+        this.list = data;
+      }
+
+      this.total = total;
+      setTimeout(() => {
+        this.listLoading = false;
+      }, 500);
+    },
+
+    resetPassword(row) {
+      const h = this.$createElement;
+      let desc = ""; // 杩欓噷淇濆瓨杈撳叆鐨勫��
+      this.$msgbox({
+        // msgbox閲岄潰濡傛灉鏄痙om鍏冪礌锛屽彧鑳芥槸鍘熺敓鐨刣om锛屽鏋滄兂鐢╡lmentui锛屽氨搴旇鎵嬪姩缁欎粬娣诲姞绫�
+        title: "閲嶇疆瀵嗙爜",
+        message: h(
+          "div",
+          {
+            class: {
+              "el-input": true,
+              "el-input--small": true,
+              "el-input--suffix": true,
+            },
+          },
+          [
+            h("input", {
+              domProps: {
+                type: "text",
+                value: desc,
+                placeholder: "璇疯緭鍏�6浣嶄互涓婂瘑鐮�",
+              },
+              class: {
+                "el-input__inner": true,
+              },
+              on: {
+                change: function (event) {
+                  desc = event.target.value; // 鐩戝惉change浜嬩欢锛屾墜鍔ㄧ殑灏嗗�肩粰淇濆瓨鍒癲esc涓�
+                },
+              },
+            }),
+          ]
+        ),
+        showCancelButton: true,
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        inputPattern: /^[0-9A-Za-z]{6,}$/,
+        inputErrorMessage: "瀵嗙爜闀垮害瑕佸ぇ浜�6浣�",
+        beforeClose: (action, instance, done) => {
+          if (action === "confirm") {
+            instance.confirmButtonLoading = true;
+            instance.confirmButtonText = "鎻愪氦...";
+            updatePassword(row.id, { newPassword: desc }).then((rsp) => {
+              if (rsp && rsp.success) {
+                this.$baseMessage(rsp.msg, "success");
+                done();
+              }
+
+              instance.confirmButtonLoading = false;
+            });
+          } else {
+            done();
+          }
+        },
+      });
+    },
+  },
+};
+</script>

--
Gitblit v1.8.0