commit f88c3868a76ed1316c6798dad37eb39274a420f4
Author: chuzhixin <1204505056@qq.com>
Date: Tue Sep 29 14:27:57 2020 +0800
🎉🎉🎉仓库重置到2020年9月29日,Vue2.6最后一个版本,之前版本不再支持,具体请查阅文档,Vue 3.0版本即将发布请耐心等待!!!
diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 0000000..f23b837
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1,4 @@
+> 1%
+last 2 versions
+not dead
+
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..4039ff1
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..1ef592b
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,5 @@
+src/assets
+src/icons
+public
+dist
+node_modules
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..0760a63
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,26 @@
+module.exports = {
+ root: true,
+ env: {
+ node: true,
+ },
+ 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",
+ },
+ overrides: [
+ {
+ files: [
+ "**/__tests__/*.{j,t}s?(x)",
+ "**/tests/unit/**/*.spec.{j,t}s?(x)",
+ ],
+ env: {
+ jest: true,
+ },
+ },
+ ],
+};
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..b9edb39
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,10 @@
+*.html text eol=lf
+*.css text eol=lf
+*.js text eol=lf
+*.scss text eol=lf
+*.vue text eol=lf
+*.hbs text eol=lf
+*.sh text eol=lf
+*.md text eol=lf
+*.json text eol=lf
+*.yml text eol=lf
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..f12c307
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+patreon: chuzhixin
+
diff --git a/.github/ISSUE_TEMPLATE/---------------.md b/.github/ISSUE_TEMPLATE/---------------.md
new file mode 100644
index 0000000..a2bb8d0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/---------------.md
@@ -0,0 +1,16 @@
+---
+name: 问题提问(不按规范提问不解答)
+about: 详细描述你的问题
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+#### 出现的问题
+
+#### 操作了什么以后出现了的
+
+#### 详细的报错截图、控制台截图
+
+#### 是否已经百度过了、是否已经努力尝试解决了
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b06c22b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+.DS_Store
+node_modules
+dist
+.env.local
+.env.*.local
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+public/video
+*.zip
+*.7z
+/src/layouts/components/zx-layouts
+/zx-templates
+/package-lock.json
diff --git a/.stylelintrc.js b/.stylelintrc.js
new file mode 100644
index 0000000..f521455
--- /dev/null
+++ b/.stylelintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: ["stylelint-config-recess-order", "stylelint-config-prettier"],
+};
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..896f53d
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,52 @@
+{
+ "[vue]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "editor.quickSuggestions": {
+ "strings": true
+ },
+ "workbench.colorTheme": "One Monokai",
+ "editor.tabSize": 2,
+ "editor.detectIndentation": false,
+ "emmet.triggerExpansionOnTab": true,
+ "editor.formatOnSave": true,
+ "javascript.format.enable": true,
+ "git.enableSmartCommit": true,
+ "git.autofetch": true,
+ "git.confirmSync": false,
+ "[json]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "liveServer.settings.donotShowInfoMsg": true,
+ "explorer.confirmDelete": false,
+ "javascript.updateImportsOnFileMove.enabled": "always",
+ "typescript.updateImportsOnFileMove.enabled": "always",
+ "files.exclude": {
+ "**/.idea": true
+ },
+ "editor.codeActionsOnSave": {
+ "source.fixAll.stylelint": true,
+ "source.fixAll.eslint": true
+ },
+ "[javascript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[scss]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[jsonc]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[html]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "editor.suggest.snippetsPreventQuickSuggestions": false,
+ "prettier.htmlWhitespaceSensitivity": "ignore",
+ "prettier.vueIndentScriptAndStyle": true,
+ "docthis.authorName": "chuzhixin 1204505056@qq.com",
+ "docthis.includeAuthorTag": true,
+ "docthis.includeDescriptionTag": true,
+ "docthis.enableHungarianNotationEvaluation": true,
+ "docthis.inferTypesFromNames": true,
+ "vetur.format.defaultFormatter.html": "prettier"
+}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a612ad9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/README-DCLOUD.md b/README-DCLOUD.md
new file mode 100644
index 0000000..2236200
--- /dev/null
+++ b/README-DCLOUD.md
@@ -0,0 +1,43 @@
+
+
vue-admin-beautiful
+
一款基于 vue+element-ui 的绝佳的通用型、中后台前端框架
+
An excellent general-purpose, middle and background front-end framework based on Vue + element UI
+
+
+[
+](https://github.com/chuzhixin/vue-admin-beautiful)
+
+## 演示地址
+
+### - [🚀 演示地址:vue-admin-beautiful (横向纵向布局无缝切换)](https://chu1204505056.gitee.io/vue-admin-beautiful/?hmsr=%E6%8F%92%E4%BB%B6%E5%B8%82%E5%9C%BA&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🚀 vue-admin-beautiful-pro 版演示地址](https://chu1204505056.gitee.io/vue-admin-beautiful-pro/?hmsr=%E6%8F%92%E4%BB%B6%E5%B8%82%E5%9C%BA&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🚀 vue-admin-beautiful-mini vue3.0 预览版地址](https://chu1204505056.gitee.io/vue-admin-beautiful-mini/?hmsr=%E6%8F%92%E4%BB%B6%E5%B8%82%E5%9C%BA&hmpl=&hmcu=&hmkw=&hmci=)
+
+## vue-admin-beautiful 前端讨论群-1 972435319
+
+不管您加或者不加,您都可以享受到开源的代码,感谢您的支持和信任,群内提供 vue-admin-beautiful-template 基础版本和详细的基础使用文档适合框架快速入门
+
+
+
+## 安装
+
+```bash
+# 克隆项目
+git clone https://github.com/chuzhixin/vue-admin-beautiful.git
+# 进入项目目录
+npm vue-admin-beautiful
+# 安装依赖
+npm i
+# 本地开发 启动项目
+cnpm run serve
+```
+
+#### github 标星增长量统计
+
+[](https://github.com/chuzhixin/vue-admin-beautiful)
+
+#### 开发者评级
+
+[](https://github.com/chuzhixin/vue-admin-beautiful)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..66d502c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,321 @@
+#
+
+
+
vue-admin-beautiful
+
一款基于 vue+element-ui 的绝佳的通用型、中后台前端框架
+
An excellent general-purpose, middle and background front-end framework based on Vue + element UI
+
+
+
+
+## vue-admin-beautiful 前端讨论群-1 972435319
+
+不管您加或者不加,您都可以享受到开源的代码,感谢您的支持和信任,群内提供 vue-admin-beautiful-template 基础版本和详细的基础使用文档适合框架快速入门
+
+
+
+## 🎉🎉🎉 基于 vue3.0 的 vue-admin-beautiful-mini 正在快马加鞭的开发,敬请期待!!!
+
+## 地址
+
+### - [🎉 演示地址 1:vue-admin-beautiful](http://beautiful.panm.cn/vue-admin-beautiful/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🎉 演示地址 2:vue-admin-beautiful](https://chu1204505056.gitee.io/vue-admin-beautiful/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🚀 pro 版演示地址 1:vue-admin-beautiful-pro](http://beautiful.panm.cn/vue-admin-beautiful-pro/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🚀 pro 版演示地址 2:vue-admin-beautiful-pro](https://chu1204505056.gitee.io/vue-admin-beautiful-pro/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🌐 github 仓库地址](https://github.com/chuzhixin/vue-admin-beautiful/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🌐 码云仓库地址](https://gitee.com/chu1204505056/vue-admin-beautiful/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+### - [🌐 vue3.0 版本研发进度展示(基础版本已全部贯通、适配电脑、手机、平板)](https://chu1204505056.gitee.io/vue-admin-beautiful-mini/?hmsr=github&hmpl=&hmcu=&hmkw=&hmci=)
+
+## 安装
+
+```bash
+# 克隆项目
+git clone https://github.com/chuzhixin/vue-admin-beautiful.git
+# 进入项目目录
+cd vue-admin-beautiful
+# 安装依赖
+npm i
+# 本地开发 启动项目
+npm run serve
+```
+
+## install
+
+```bash
+# Clone project
+git clone https://github.com/chuzhixin/vue-admin-beautiful.git
+# Enter project directory
+cd vue-admin-beautiful
+# Installation dependency
+npm i
+# Start project
+npm run serve
+```
+
+## 友情链接
+
+### - [uView 文档(超棒的移动跨端框架,文档详细,上手容易)](https://uviewui.com/)
+
+### - [Element UI 表单设计及代码生成器(可视化表单设计器,一键生成 element 表单)](https://github.com/JakHuang/form-generator/)
+
+### - [luch-request(基于 Promise 开发的 uni-app 跨平台、项目级别的请求库,它有更小的体积,易用的 api,方便简单的自定义能力)](https://www.quanzhan.co/luch-request/)
+
+### - [umyui 文档(开发者准备的基于 Vue 2.0 的桌面端组件库; 流畅渲染表格万级数据)](http://www.umyui.com/)
+
+## setting.js 配置
+
+- 说明:这里有好多你会用到的配置项。
+- 位置:src/config/settings.js
+- 注意:此处可能不是最新代码具体可查看[github 最新的 settings.js 配置](https://github.com/chuzhixin/vue-admin-beautiful/blob/master/src/config/settings.js)
+- 示例代码:
+
+```js
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局变量配置
+ */
+module.exports = {
+ // 开发以及部署时的URL
+ publicPath: "",
+ // 生产环境构建文件的目录名
+ outputDir: "dist",
+ // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
+ assetsDir: "static",
+ // 开发环境每次保存时是否输出为eslint编译警告
+ lintOnSave: true,
+ // 进行编译的依赖
+ transpileDependencies: ["vue-echarts", "resize-detector", "zx-layouts"],
+ // 默认的接口地址 如果是开发环境和生产环境走vab-mock-server,当然你也可以选择自己配置成需要的接口地址
+ baseURL:
+ process.env.NODE_ENV === "development"
+ ? "vab-mock-server"
+ : "vab-mock-server",
+ //标题 (包括初次加载雪花屏的标题 页面的标题 浏览器的标题)
+ title: "vue-admin-beautiful",
+ //简写
+ abbreviation: "vab",
+ //开发环境端口号
+ devPort: "80",
+ //版本号
+ version: process.env.VUE_APP_VERSION,
+ //烦请保留package.json作者信息 保留版权可免费商用
+ copyright: process.env.VUE_APP_AUTHOR,
+ //是否显示页面底部版权信息,建议您显示,当然您也可以选择不显示,不管您是付费用户还是未付费用户您都有选择显示或者不显示的权利
+ footerCopyright: process.env.NODE_ENV !== "development" ? true : false,
+ //是否显示右上角github图标
+ githubCorner: process.env.NODE_ENV !== "development" ? true : false,
+ //是否显示顶部进度条
+ progressBar: true,
+ //缓存路由的最大数量
+ keepAliveMaxNum: 99,
+ // 路由模式,可选值为 history 或 hash
+ routerMode: "hash",
+ //不经过token校验的路由
+ routesWhiteList: ["/login", "/register", "/404", "/401"],
+ //加载时显示文字
+ loadingText: "正在加载中...",
+ //token名称
+ tokenName: "accessToken",
+ //token在localStorage、sessionStorage、cookie存储的key的名称
+ tokenTableName: "vue-admin-beautiful",
+ //token存储位置localStorage sessionStorage cookie
+ storage: "localStorage",
+ //token失效回退到登录页时是否记录本次的路由
+ recordRoute: true,
+ //是否显示logo,不显示时设置false,显示时请填写remixIcon图标名称,暂时只支持设置remixIcon
+ logo: "vuejs-fill",
+ //是否国定头部 固定fixed 不固定noFixed
+ header: "fixed",
+ //横纵布局 horizontal vertical
+ layout: "vertical",
+ //是否开启主题配置按钮
+ themeBar: true,
+ //是否显示多标签页
+ tagsBar: true,
+ //是否显示骨架屏
+ skeleton: false,
+ //配后端数据的接收方式application/json;charset=UTF-8或者application/x-www-form-urlencoded;charset=UTF-8
+ contentType: "application/json;charset=UTF-8",
+ //消息框消失时间
+ messageDuration: 3000,
+ //最长请求时间
+ requestTimeout: 5000,
+ //操作正常code
+ successCode: 200,
+ //登录失效code
+ invalidCode: 402,
+ //无权限code
+ noPermissionCode: 401,
+ //是否显示在页面高亮错误
+ errorLog: ["development", "test", "production"],
+ //是否开启登录拦截
+ loginInterception: true,
+ //是否开启登录RSA加密
+ loginRSA: false,
+ //是否依据mock数据生成webstorm HTTP Request请求文件
+ httpRequestFile: false,
+ //intelligence和all两种方式,前者后端权限只控制permissions不控制view文件的import(前后端配合,减轻后端工作量),all方式完全交给后端前端只负责加载
+ authentication: "intelligence",
+ //vertical布局时是否只保持一个子菜单的展开
+ uniqueOpened: true,
+ //vertical布局时默认展开的菜单path,使用逗号隔开建议只展开一个
+ defaultOopeneds: ["/vab"],
+ //需要加loading层的请求,防止重复提交
+ debounce: ["doEdit"],
+ //需要自动注入并加载的模块
+ providePlugin: { maptalks: "maptalks", "window.maptalks": "maptalks" },
+ //npm run build时是否自动生成7z压缩包
+ build7z: false,
+ //代码生成机生成在view下的文件夹名称
+ templateFolder: "project",
+};
+```
+
+## variables.scss 配置
+
+- 说明:这里可以修改你项目的配色方案,简单修改即可实现风格大变。
+- 位置:src/styles/variables.scss
+- 注意:此处可能不是最新代码具体可查看[github 最新的 variables.scss 配置](https://github.com/chuzhixin/vue-admin-beautiful/blob/master/src/styles/variables.scss)
+
+```scss
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局主题变量配置,VIP文档内提供多种好看的配色方案(ant-design风格、layui风格、iview风格),请查看VIP文档主题配置篇
+ */
+/* stylelint-disable */
+@charset "utf-8";
+//框架默认主题色
+$base-color-default: #1890ff;
+//默认层级
+$base-z-index: 999;
+//横向布局纵向布局时菜单背景色
+$base-menu-background: #001529;
+//菜单文字颜色
+$base-menu-color: hsla(0, 0%, 100%, 0.95);
+//菜单选中文字颜色
+$base-menu-color-active: hsla(0, 0%, 100%, 0.95);
+//菜单选中背景色
+$base-menu-background-active: $base-color-default;
+//标题颜色
+$base-title-color: #fff;
+//字体大小配置
+$base-font-size-small: 12px;
+$base-font-size-default: 14px;
+$base-font-size-big: 16px;
+$base-font-size-bigger: 18px;
+$base-font-size-max: 22px;
+$base-font-color: #606266;
+$base-color-blue: $base-color-default;
+$base-color-green: #13ce66;
+$base-color-white: #fff;
+$base-color-black: #000;
+$base-color-yellow: #ffba00;
+$base-color-orange: #ff6700;
+$base-color-red: #ff4d4f;
+$base-color-gray: rgba(0, 0, 0, 0.65);
+$base-main-width: 1279px;
+$base-border-radius: 2px;
+$base-border-color: #dcdfe6;
+//输入框高度
+$base-input-height: 32px;
+//默认paddiing
+$base-padding: 20px;
+//默认阴影
+$base-box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+//横向布局时top-bar、logo、一级菜单的高度
+$base-top-bar-height: 65px;
+//纵向布局时logo的高度
+$base-logo-height: 75px;
+//顶部nav-bar的高度
+$base-nav-bar-height: 60px;
+//顶部多标签页tags-bar的高度
+$base-tags-bar-height: 55px;
+//顶部多标签页tags-bar中每一个item的高度
+$base-tag-item-height: 34px;
+//菜单li标签的高度
+$base-menu-item-height: 50px;
+//app-main的高度
+$base-app-main-height: calc(
+ 100vh - #{$base-nav-bar-height} - #{$base-tags-bar-height} -
+ #{$base-padding} - #{$base-padding} - 55px - 30px
+);
+//纵向布局时左侧导航未折叠时的宽度
+$base-left-menu-width: 230px;
+//纵向布局时左侧导航未折叠时右侧内容的宽度
+$base-right-content-width: calc(100% - #{$base-left-menu-width});
+//纵向布局时左侧导航已折叠时的宽度
+$base-left-menu-width-min: 65px;
+//纵向布局时左侧导航已折叠时右侧内容的宽度
+$base-right-content-width-min: calc(100% - #{$base-left-menu-width-min});
+//默认动画
+$base-transition: all 0.2s;
+//默认动画时长
+$base-transition-time: 0.2s;
+
+:export {
+ //菜单文字颜色变量导出
+ menu-color: $base-menu-color;
+ //菜单选中文字颜色变量导出
+ menu-color-active: $base-menu-color-active;
+ //菜单背景色变量导出
+ menu-background: $base-menu-background;
+ //菜单选中背景色变量导出
+ menu-background-active: $base-menu-background-active;
+ //多标签页选中背景色变量导出
+ tag-background-active: $base-color-blue;
+ //默认按钮背景色变量导出
+ button-background: $base-color-blue;
+ //分页选中背景色变量导出
+ pagination-background-active: $base-color-blue;
+}
+```
+
+## element-ui 组件尺寸配置
+
+- 说明:这里可以修改你 element-ui 组件尺寸,element-ui 组件的尺寸一共分为 large、default、small 、mini,本项目默认使用的是 small。
+- 位置:src/plugins/element.js
+- 示例代码:
+
+```js
+import Vue from "vue";
+import ElementUI from "element-ui";
+import "element-ui/lib/theme-chalk/display.css";
+
+import "@/styles/element-variables.scss";
+
+Vue.use(ElementUI, {
+ size: "small", // element-ui组件的尺寸一共分为large、default、small 、mini
+});
+```
+
+## 付费技术支持,商务合作
+
+### 联系:QQ 1204505056
+
+## 捐赠
+
+
+
+#### github 标星增长量统计
+
+[](https://github.com/chuzhixin/vue-admin-beautiful)
+
+#### 开发者评级
+
+[](https://github.com/chuzhixin/vue-admin-beautiful)
+
+## 关于框架的声明
+
+框架在保留作者版权信息的前提下可免费用于商业使用,框架所有代码包含 npm 包中的源码内容均为免费开放,如果您愿意支持我、或者希望完全变成自己的版权信息,需支付 299 元,如果您愿意加入 VIP 群学习需支付 100 元,这一切都是在您自愿的基础上,如果您觉得框架一文不值,请直接略过,高抬贵手放我一马,不要恶意刷差评,希望每个使用 vue-admin-beautiful 的人无论过程怎样,结局都是美好的,联系方式 QQ 1204505056
+
+## vue-admin-beautiful 前端讨论群-2 1139183756
+
+不管您加或者不加,您都可以享受到开源的代码,感谢您的支持和信任,群内提供 vue-admin-beautiful-template 基础版本和详细的基础使用文档适合框架快速入门
+
+
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..034e848
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,21 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 5.1.x | :white_check_mark: |
+| 5.0.x | :x: |
+| 4.0.x | :white_check_mark: |
+| < 4.0 | :x: |
+
+## Reporting a Vulnerability
+
+Use this section to tell people how to report a vulnerability.
+
+Tell them where to go, how often they can expect to get an update on a
+reported vulnerability, what to expect if the vulnerability is accepted or
+declined, etc.
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..162a3ea
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ["@vue/cli-plugin-babel/preset"],
+};
diff --git a/deploy.sh b/deploy.sh
new file mode 100644
index 0000000..07c7ef6
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -e
+npm run build
+cd dist
+touch .nojekyll
+git init
+git add -A
+git commit -m '🎉🎉🎉仓库重置到2020年9月29日,Vue2.6最后一个版本,之前版本不再支持,具体请查阅文档,Vue 3.0版本请耐心等待!!!'
+git push -f "https://${access_token}@gitee.com/chu1204505056/vue-admin-beautiful.git" master:gh-pages
+start "https://gitee.com/chu1204505056/vue-admin-beautiful/pages"
+git push -f "https://${access_token}@github.com/chuzhixin/vue-admin-beautiful.git" master:gh-pages
+cd -
+exec /bin/bash
+
+
+
+
diff --git a/http/mock.http b/http/mock.http
new file mode 100644
index 0000000..9f437b5
--- /dev/null
+++ b/http/mock.http
@@ -0,0 +1,70 @@
+
+###/changeLog/getList###mockServer
+POST http://localhost:80/mock-server/changeLog/getList
+Content-Type: application/x-www-form-urlencoded
+###
+mockServer
+###/colorfulIcon/list###
+POST http://localhost:80/mock-server/colorfulIcon/list
+Content-Type: application/x-www-form-urlencoded
+###mockServer
+
+###/menu/navigate###
+POST http://localhost:80/mock-server/menu/navigate
+Content-Type: application/x-www-form-urlenmockServer
+###
+
+###/icon/list###
+POST http://localhost:80/mock-server/icon/mockServer
+Content-Type: application/x-www-form-urlencoded
+###
+
+###/face/list###mockServer
+POST http://localhost:80/mock-server/face/list
+Content-Type: application/x-www-form-urlencoded
+###
+mockServer
+###/table/list###
+POST http://localhost:80/mock-server/table/list
+Content-Type: application/x-www-form-urlencoded
+###mockServer
+
+###/remixicon/getList###
+POST http://localhost:80/mock-server/remixicon/getList
+Content-Type: application/x-www-form-urlenmockServer
+###
+
+###/publicKey###
+POST http://localhost:80/mock-server/pumockServer
+Content-Type: application/x-www-form-urlencoded
+###
+
+###/tree/list###mockServer
+POST http://localhost:80/mock-server/tree/list
+Content-Type: application/x-www-form-urlencoded
+###
+mockServer
+###/upload###
+POST http://localhost:80/mock-server/upload
+Content-Type: application/x-www-form-urlencoded
+###mockServer
+
+###/login###
+POST http://localhost:80/mock-server/login
+Content-Type: application/x-www-form-urlenmockServer
+###
+
+###/waterfall/list###
+POST http://localhost:80/mock-server/waterfall/list
+Content-Type: application/x-www-form-urlencoded
+###
+
+###/logout###
+POST http://localhost:80/mock-server/logout
+Content-Type: application/x-www-form-urlencoded
+###
+
+###/userInfo###
+POST http://localhost:80/mock-server/userInfo
+Content-Type: application/x-www-form-urlencoded
+###
diff --git a/license.md b/license.md
new file mode 100644
index 0000000..a612ad9
--- /dev/null
+++ b/license.md
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/mock/controller/ad.js b/mock/controller/ad.js
new file mode 100644
index 0000000..961b9d7
--- /dev/null
+++ b/mock/controller/ad.js
@@ -0,0 +1,19 @@
+const data = [
+ {
+ title: "vue-admin-beautiful-pro beta版本已发布,点我提前体验",
+ url: "https://chu1204505056.gitee.io/vue-admin-beautiful-pro/#/index",
+ },
+];
+module.exports = [
+ {
+ url: "/ad/getList",
+ type: "get",
+ response() {
+ return {
+ code: 200,
+ msg: "success",
+ data,
+ };
+ },
+ },
+];
diff --git a/mock/controller/blacklist.js b/mock/controller/blacklist.js
new file mode 100644
index 0000000..6ad29c4
--- /dev/null
+++ b/mock/controller/blacklist.js
@@ -0,0 +1,87 @@
+const data = [
+ {
+ name: "奉/fendou飘逸的梦",
+ qq: "812770127",
+ excuse: "上来就开骂,不可原谅",
+ },
+ {
+ name: "江荻",
+ qq: "2324945654",
+ excuse: "上来就开骂,不可原谅",
+ },
+ {
+ name: "Diamond",
+ qq: "494904935",
+ excuse: "跟我道歉可以选择原谅",
+ },
+ {
+ name: "Mr、无涯",
+ qq: "2198457489",
+ excuse: "已原谅",
+ },
+ {
+ name: "玩世不恭丶江小白",
+ qq: "1779263221",
+ excuse: "睁眼说瞎话",
+ },
+ {
+ name: "福州客家网络科技有限公司(潘芳林等兄弟二人)",
+ qq: "1409198410、1778486252",
+ excuse:
+ "剽窃、破解框架授权并发布到网上还伪装成善人,公开道歉并尊重我的劳动成果可以选择原谅",
+ },
+ {
+ name: "willina",
+ qq: "405522648",
+ excuse:
+ "上来就开骂道:You and your git submit are just a rubbish,不可原谅",
+ },
+ {
+ name: "7(赵海鹏)",
+ qq: "252334666",
+ excuse: "欺骗两个善良的小姑娘,做完项目不付70%的尾款,强烈抵制",
+ },
+ {
+ name: "生活,一半记忆.一半继续",
+ qq: "252667193",
+ excuse: "30多岁,不学无术,造谣抹黑,不可原谅",
+ },
+ {
+ name: "AIRLOO",
+ qq: "5971794",
+ excuse: "已原谅",
+ },
+ {
+ name: "master Z",
+ qq: "1832819123",
+ excuse: "不尊重别人的劳动成果,认为开源就得无偿替他服务,不可原谅",
+ },
+ {
+ name: "想象中。。。",
+ qq: "329492979",
+ excuse: "不尊重别人的劳动成果,认为开源就得无偿替他服务,不可原谅",
+ },
+ {
+ name: "苏潍—菏泽微智科技",
+ qq: "328580081",
+ excuse: "无言以对",
+ },
+ {
+ name: "罗阳",
+ qq: "1320168680",
+ excuse: "不尊重别人的劳动成果,认为开源就得无偿替他服务,不可原谅",
+ },
+];
+module.exports = [
+ {
+ url: "/blacklist/getList",
+ type: "post",
+ response() {
+ return {
+ code: 200,
+ msg: "success",
+ data,
+ };
+ },
+ },
+];
diff --git a/mock/controller/changeLog.js b/mock/controller/changeLog.js
new file mode 100644
index 0000000..47992fa
--- /dev/null
+++ b/mock/controller/changeLog.js
@@ -0,0 +1,200 @@
+const data = [
+ {
+ content: "在github上获得了第一个star,感恩一位名叫Bequiet2014的github用户",
+ timestamp: "2020-03-23",
+ },
+ {
+ content: "增加更换主题功能",
+ timestamp: "2020-04-10",
+ },
+ {
+ content: "大幅精简代码",
+ timestamp: "2020-04-14",
+ },
+ {
+ content: "修复群友反馈的bug",
+ timestamp: "2020-04-16",
+ },
+ {
+ content: "剔除maptalks",
+ timestamp: "2020-04-17",
+ },
+ {
+ content:
+ "换行符统一修改为lf 支持苹果 linux windows协同开发 强制开启最严格eslint规则 不要哭 严格是有好处的",
+ timestamp: "2020-04-17",
+ },
+ {
+ content: "彻底完成手机端适配,记录这一天熬夜到了晚上三点",
+ timestamp: "2020-04-18",
+ },
+ {
+ content:
+ "删除babel-polyfill 提高打包速度 减少压缩体积(放弃ie是这个项目做出的最伟大的决定)",
+ 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: "优化登录退出逻辑 代码更清晰 退出不再重载网页 改为重载路由形式",
+ timestamp: "2020-04-26",
+ },
+ {
+ content: "无端的指责只会让我更加努力 修复sidebar 简化permission",
+ timestamp: "2020-04-28",
+ },
+ {
+ content: "又是一个深夜 实现了表格增删改查的一键生成",
+ timestamp: "2020-04-30",
+ },
+ {
+ content: "大幅优化tagsview标签动画",
+ timestamp: "2020-05-02",
+ },
+ {
+ content: "三种图标组件实现mock模拟分页",
+ timestamp: "2020-05-03",
+ },
+ {
+ content: "添加了markdown编辑器组件",
+ 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: "又被人骂了 挺好的 让我下定决心重写了tagsBar",
+ timestamp: "2020-05-20",
+ },
+ {
+ content: "仿ant-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: "彻底完成了tagsbar多标签页的重构",
+ timestamp: "2020-06-22",
+ },
+ {
+ content: "感恩github标星过3.0K 祝大家端午节快乐",
+ timestamp: "2020-06-25",
+ },
+ {
+ content: "彻底重构了SideBar与TopBar 大幅精简dom渲染逻辑 全球首发",
+ timestamp: "2020-06-25",
+ },
+ {
+ content: "添加菜单管理",
+ timestamp: "2020-07-7",
+ },
+ {
+ content: "首次采用sass-loader 9.0写法,感谢github用户 shaonialife",
+ timestamp: "2020-07-7",
+ },
+ {
+ content: "添加vue-amap组件",
+ timestamp: "2020-07-11",
+ },
+ {
+ content: "修改zx-layouts引入方式",
+ timestamp: "2020-07-15",
+ },
+ {
+ content:
+ "记录这一天vue-admin-beautiful在插件市场、百度已花费超过1万元广告费用,希望一切都值得",
+ timestamp: "2020-07-18",
+ },
+ {
+ content: "主题配置添加海洋之心、绿荫草场、荣耀典藏、暗黑之子模式",
+ timestamp: "2020-07-18",
+ },
+ {
+ content: "全局axios请求全面支持Status Code拦截处理",
+ timestamp: "2020-07-29",
+ },
+ {
+ content: "重构全局loadding加载代码",
+ timestamp: "2020-07-31",
+ },
+ {
+ content: "升级stylelint自动排序功能",
+ timestamp: "2020-08-25",
+ },
+ {
+ content: "修复视频播放器组件重载路由失效的bug",
+ timestamp: "2020-09-03",
+ },
+ {
+ content: "修复极个别情况image-loader打包报错",
+ timestamp: "2020-09-18",
+ },
+ {
+ content: "全网首个基于vue3.0开发的admin框架已发布,具体请访问github",
+ timestamp: "2020-09-22",
+ },
+];
+
+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
new file mode 100644
index 0000000..e32a5dd
--- /dev/null
+++ b/mock/controller/colorfulIcon.js
@@ -0,0 +1,328 @@
+const data = [
+ "alphabetical_sorting",
+ "advance",
+ "address_book",
+ "alphabetical_sorting",
+ "advertising",
+ "alarm_clock",
+ "area_chart",
+ "approval",
+ "answers",
+ "approve",
+ "assistant",
+ "audio_file",
+ "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/goodsDetail.js b/mock/controller/goodsDetail.js
new file mode 100644
index 0000000..9548163
--- /dev/null
+++ b/mock/controller/goodsDetail.js
@@ -0,0 +1,42 @@
+const { mock } = require("mockjs");
+
+module.exports = [
+ {
+ url: "/goodsDetail/getList",
+ type: "post",
+ response(config) {
+ return {
+ code: 200,
+ msg: "success",
+ totalCount: 999,
+ data: mock({
+ "data|10": [
+ {
+ id: "@id",
+ },
+ ],
+ }).data,
+ };
+ },
+ },
+ {
+ url: "/goodsDetail/doEdit",
+ type: "post",
+ response(config) {
+ return {
+ code: 200,
+ msg: "模拟保存成功",
+ };
+ },
+ },
+ {
+ url: "/goodsDetail/doDelete",
+ type: "post",
+ response(config) {
+ return {
+ code: 200,
+ msg: "模拟删除成功",
+ };
+ },
+ },
+];
diff --git a/mock/controller/goodsList.js b/mock/controller/goodsList.js
new file mode 100644
index 0000000..9f2420d
--- /dev/null
+++ b/mock/controller/goodsList.js
@@ -0,0 +1,43 @@
+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
new file mode 100644
index 0000000..b772706
--- /dev/null
+++ b/mock/controller/icon.js
@@ -0,0 +1,989 @@
+const data = [
+ "ad",
+ "address-book",
+ "address-card",
+ "adjust",
+ "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
new file mode 100644
index 0000000..9a2520d
--- /dev/null
+++ b/mock/controller/menuManagement.js
@@ -0,0 +1,51 @@
+module.exports = [
+ {
+ url: "/menuManagement/getTree",
+ type: "post",
+ response(config) {
+ 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(config) {
+ return {
+ code: 200,
+ msg: "模拟保存成功",
+ };
+ },
+ },
+ {
+ url: "/menuManagement/doDelete",
+ type: "post",
+ response(config) {
+ return {
+ code: 200,
+ msg: "模拟删除成功",
+ };
+ },
+ },
+];
diff --git a/mock/controller/notice.js b/mock/controller/notice.js
new file mode 100644
index 0000000..8ab5c6f
--- /dev/null
+++ b/mock/controller/notice.js
@@ -0,0 +1,38 @@
+const data = [
+ {
+ title: "究竟是什么样的终点,才配得上这一路的颠沛流离。。。",
+ closable: false,
+ type: "success",
+ },
+ {
+ title:
+ "作者寄语:感谢Star,感恩相遇,愿世间美好与我们环环相扣,加油!屏幕前的我们,打破桎梏,坚守初心。其实人生改变命运的机会并没有太多,我们并不是不优秀,我们也并不是一无是处,我们也希望驻足山巅被众人仰望,也许我们缺少的只是一个机会,缺少的只是生命中的导师,我希望这个框架帮助到更多的人,希望有一天,我们面试的时候不再胆怯,希望有一天别人看到的不仅仅是你的努力,还有你的功成名就,出人头地。",
+ closable: false,
+ type: "warning",
+ },
+ {
+ title:
+ "鸣谢:尤雨溪、蒋豪群、element-ui、唐金州、花裤衩、贤心、iView、uView的开源项目给我带来的很多的灵感,弱小的人才习惯嘲讽与否定,内心强大的人从不吝啬赞美与鼓励,人生在世,得到每个人的认可几乎是痴心妄想,我也只是一条略懂前端的咸鱼,可我仍一直怀揣着改变世界的梦想,希望我们每个人,不管过程怎样,结局都是美好的。",
+ closable: false,
+ type: "success",
+ },
+ {
+ title:
+ "随笔:我一直在寻找开源的真谛,我一直再想什么是开源,我一开始觉得免费就是开源,好像又不是。我理解的开源是:你也开源,我也开源,大家一起贡献,相互帮助。我最担心的事情是:我一个小人物,去伺候一众的伸手党,我想,这不是开源该有的氛围。我还太年轻,不懂什么是格局,我只知道,无私的帮助他人,能给我带来快乐,却不能给我带来收入,当然,有时候,快乐对我来说就已经足够了。可惜我是一个人,没有精力帮助到每一个人,可惜这个世界需要赚钱,才能过上平凡的生活,可惜了我的梦想,这个物欲横流的时代,理想主义的我们,即使内心坚决如铁,也似乎寸步难行。",
+ 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
new file mode 100644
index 0000000..776969f
--- /dev/null
+++ b/mock/controller/personalCenter.js
@@ -0,0 +1,42 @@
+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(config) {
+ return {
+ code: 200,
+ msg: "模拟保存成功",
+ };
+ },
+ },
+ {
+ url: "/personalCenter/doDelete",
+ type: "post",
+ response(config) {
+ return {
+ code: 200,
+ msg: "模拟删除成功",
+ };
+ },
+ },
+];
diff --git a/mock/controller/remixIcon.js b/mock/controller/remixIcon.js
new file mode 100644
index 0000000..abe57eb
--- /dev/null
+++ b/mock/controller/remixIcon.js
@@ -0,0 +1,2296 @@
+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",
+ "advertisement-fill",
+ "advertisement-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
new file mode 100644
index 0000000..f1f30d8
--- /dev/null
+++ b/mock/controller/roleManagement.js
@@ -0,0 +1,53 @@
+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
new file mode 100644
index 0000000..fd7026c
--- /dev/null
+++ b/mock/controller/router.js
@@ -0,0 +1,390 @@
+const data = [
+ {
+ path: "/",
+ component: "Layout",
+ redirect: "index",
+ children: [
+ {
+ path: "index",
+ name: "Index",
+ component: "views/index/index",
+ meta: {
+ title: "首页",
+ icon: "home",
+ affix: true,
+ },
+ },
+ ],
+ },
+ {
+ path: "/personalCenter",
+ component: "Layout",
+ hidden: true,
+ redirect: "personalCenter",
+ children: [
+ {
+ path: "personalCenter",
+ name: "PersonalCenter",
+ component: "views/personalCenter/index",
+ meta: {
+ title: "个人中心",
+ },
+ },
+ ],
+ },
+ {
+ 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: "remixIcon",
+ name: "RemixIcon",
+ component: "views/vab/icon/remixIcon",
+ meta: { title: "小清新图标" },
+ },
+ {
+ path: "colorfulIcon",
+ name: "ColorfulIcon",
+ component: "views/vab/icon/colorfulIcon",
+ meta: { title: "多彩图标" },
+ },
+ ],
+ },
+ {
+ path: "table",
+ component: "EmptyLayout",
+ redirect: "noRedirect",
+ name: "Table",
+ meta: {
+ title: "表格",
+ permissions: ["admin"],
+ },
+ children: [
+ {
+ path: "comprehensiveTable",
+ name: "ComprehensiveTable",
+ component: "views/vab/table/index",
+ meta: { title: "综合表格" },
+ },
+ {
+ path: "inlineEditTable",
+ name: "InlineEditTable",
+ component: "views/vab/table/inlineEditTable",
+ meta: { title: "行内编辑" },
+ },
+ ],
+ },
+ {
+ 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: "card",
+ name: "Card",
+ component: "views/vab/card/index",
+ meta: { title: "卡片", permissions: ["admin"] },
+ },
+
+ {
+ path: "betterScroll",
+ name: "BetterScroll",
+ component: "views/vab/betterScroll/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: "echarts",
+ name: "Echarts",
+ component: "views/vab/echarts/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: "qrCode",
+ name: "QrCode",
+ component: "views/vab/qrCode/index",
+ meta: { title: "二维码", permissions: ["admin"] },
+ },
+ {
+ 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: "imgComparison",
+ name: "ImgComparison",
+ component: "views/vab/imgComparison/index",
+ meta: { title: "图像拖拽比对", permissions: ["admin"] },
+ },
+ {
+ path: "codeGenerator",
+ name: "CodeGenerator",
+ component: "views/vab/codeGenerator/index",
+ meta: { title: "代码生成机", permissions: ["admin"] },
+ },
+ {
+ path: "markdown",
+ name: "Markdown",
+ component: "views/vab/markdown/index",
+ meta: { title: "markdown阅读器", 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: "sticky",
+ name: "Sticky",
+ component: "views/vab/sticky/index",
+ meta: { title: "sticky吸附", 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: "goodsDetail",
+ name: "GoodsDetail",
+ component: "views/mall/goodsDetail/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
new file mode 100644
index 0000000..fa4c38e
--- /dev/null
+++ b/mock/controller/table.js
@@ -0,0 +1,88 @@
+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
new file mode 100644
index 0000000..d0efd8d
--- /dev/null
+++ b/mock/controller/tree.js
@@ -0,0 +1,54 @@
+const data = [
+ {
+ id: "1",
+ parentId: "0",
+ name: "vue-admin-beautiful科技有限公司",
+ title: "vue-admin-beautiful科技有限公司",
+ text: "vue-admin-beautiful科技有限公司",
+ value: "1",
+ rank: 1,
+ children: [
+ {
+ id: "32816b88ff72423f960e7d492a386131",
+ parentId: "1",
+ name: "1103工作室",
+ title: "1103工作室",
+ text: "1103工作室",
+ value: "32816b88ff72423f960e7d492a386131",
+ rank: 2,
+ children: [
+ {
+ id: "9e11afc35d55475fb0bd3164b9684cbe",
+ parentId: "32816b88ff72423f960e7d492a386131",
+ name: "前端牛逼plus小组",
+ title: "前端牛逼plus小组",
+ text: "前端牛逼plus小组",
+ value: "9e11afc35d55475fb0bd3164b9684cbe",
+ rank: 3,
+ children: [
+ {
+ id: "4cc1b04635e4444292526c5391699077",
+ parentId: "9e11afc35d55475fb0bd3164b9684cbe",
+ name: "组员chuzhixin",
+ title: "组员chuzhixin",
+ text: "组员chuzhixin",
+ value: "4cc1b04635e4444292526c5391699077",
+ rank: 4,
+ children: [],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+];
+module.exports = [
+ {
+ url: "/tree/list",
+ type: "post",
+ response() {
+ return { code: 200, msg: "success", data };
+ },
+ },
+];
diff --git a/mock/controller/upload.js b/mock/controller/upload.js
new file mode 100644
index 0000000..a6f9ab0
--- /dev/null
+++ b/mock/controller/upload.js
@@ -0,0 +1,14 @@
+const data = [];
+module.exports = [
+ {
+ url: "/upload",
+ type: "post",
+ response(config) {
+ return {
+ code: 200,
+ msg: "success",
+ data: data,
+ };
+ },
+ },
+];
diff --git a/mock/controller/user.js b/mock/controller/user.js
new file mode 100644
index 0000000..de02fec
--- /dev/null
+++ b/mock/controller/user.js
@@ -0,0 +1,95 @@
+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: "帐户或密码不正确。",
+ };
+ }
+ 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
new file mode 100644
index 0000000..30749eb
--- /dev/null
+++ b/mock/controller/userManagement.js
@@ -0,0 +1,70 @@
+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
new file mode 100644
index 0000000..68566c0
--- /dev/null
+++ b/mock/index.js
@@ -0,0 +1,16 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 导入所有 controller 模块,npm run serve时在node环境中自动输出controller文件夹下Mock接口,请勿修改。
+ */
+
+const { handleMockArray } = require("./utils");
+
+const mocks = [];
+const mockArray = handleMockArray();
+mockArray.forEach((item) => {
+ const obj = require(item);
+ mocks.push(...obj);
+});
+module.exports = {
+ mocks,
+};
diff --git a/mock/mockServer.js b/mock/mockServer.js
new file mode 100644
index 0000000..23944fd
--- /dev/null
+++ b/mock/mockServer.js
@@ -0,0 +1,94 @@
+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/settings");
+const mockDir = path.join(process.cwd(), "mock");
+
+/**
+ *
+ * @param app
+ * @returns {{mockStartIndex: number, mockRoutesLength: number}}
+ */
+const registerRoutes = (app) => {
+ let mockLastIndex;
+ const { mocks } = require("./index.js");
+ 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.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
new file mode 100644
index 0000000..9f04d42
--- /dev/null
+++ b/mock/utils/index.js
@@ -0,0 +1,43 @@
+const { Random } = require("mockjs");
+const { join } = require("path");
+const fs = require("fs");
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 随机生成图片url。
+ * @param width
+ * @param height
+ * @returns {string}
+ */
+function handleRandomImage(width = 50, height = 50) {
+ return `https://picsum.photos/${width}/${height}?random=${Random.guid()}`;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 处理所有 controller 模块,npm run serve时在node环境中自动输出controller文件夹下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/package.json b/package.json
new file mode 100644
index 0000000..5ab4110
--- /dev/null
+++ b/package.json
@@ -0,0 +1,132 @@
+{
+ "name": "vue-admin-beautiful",
+ "version": "1.0.0",
+ "author": "chuzhixin 1204505056@qq.com",
+ "participants": [],
+ "homepage": "https://chu1204505056.gitee.io/vue-admin-beautiful",
+ "publishConfig": {
+ "registry": "https://npm.pkg.github.com/"
+ },
+ "scripts": {
+ "serve": "vue-cli-service serve",
+ "build": "vue-cli-service build",
+ "build:report": "vue-cli-service build --report",
+ "globle": "npm install -g cnpm --registry=https://registry.npm.taobao.org&&cnpm i rimraf npm-check-updates nrm -g&&rimraf node_modules&&cnpm i",
+ "lint": "vue-cli-service lint --fix",
+ "lint:style": "stylelint-config-prettier-check",
+ "inspect": "vue-cli-service inspect",
+ "template": "plop",
+ "clear": "rimraf node_modules&&cnpm i&&increase-memory-limit",
+ "use:npm": "nrm use npm",
+ "use:taobao": "nrm use taobao",
+ "update": "ncu -u --concurrency 10 --timeout 80000&&cnpm i",
+ "update:globle": "ncu -g --concurrency 10 --timeout 80000",
+ "svgo": "svgo -f src/remixIcon/svg --config=svgo.yml",
+ "push": "start ./push.sh",
+ "deploy": "start ./deploy.sh",
+ "increase-memory-limit": "increase-memory-limit"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/chuzhixin/vue-admin-beautiful.git"
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "lint-staged"
+ }
+ },
+ "lint-staged": {
+ "src/**/*.{js,vue}": [
+ "eslint --fix",
+ "git add"
+ ]
+ },
+ "dependencies": {
+ "axios": "^0.20.0",
+ "better-scroll": "^2.0.4",
+ "clipboard": "^2.0.6",
+ "codemirror": "^5.58.1",
+ "core-js": "^3.6.5",
+ "dayjs": "^1.9.0",
+ "echarts": "^4.9.0",
+ "echarts-wordcloud": "^1.1.3",
+ "element-ui": "^2.13.2",
+ "file-saver": "^2.0.2",
+ "js-cookie": "^2.2.1",
+ "jsencrypt": "^3.0.0-rc.1",
+ "jsonlint": "^1.6.3",
+ "lodash": "^4.17.20",
+ "maptalks": "^0.49.1",
+ "mapv": "^2.0.57",
+ "nprogress": "^0.2.0",
+ "qs": "^6.9.4",
+ "screenfull": "^5.0.2",
+ "vue": "^2.6.12",
+ "vue-amap": "^0.5.10",
+ "vue-echarts": "^5.0.0-beta.0",
+ "vue-qart": "^2.2.0",
+ "vue-router": "^3.4.5",
+ "vuedraggable": "^2.24.1",
+ "vuex": "^3.5.1",
+ "zx-comparison": "^1.0.3",
+ "zx-count": "^0.3.7",
+ "zx-icon": "^1.1.9",
+ "zx-keel": "^0.9.4",
+ "zx-layouts": "^0.6.13",
+ "zx-magnifie": "^0.4.0",
+ "zx-markdown-editor": "^0.0.2",
+ "zx-player": "^1.0.1",
+ "zx-quill": "^0.0.2",
+ "zx-templates": "^0.0.22",
+ "zx-verify": "^0.0.2"
+ },
+ "devDependencies": {
+ "@babel/register": "^7.11.5",
+ "@vue/cli-plugin-babel": "^4.5.6",
+ "@vue/cli-plugin-eslint": "^4.5.6",
+ "@vue/cli-plugin-router": "^4.5.6",
+ "@vue/cli-plugin-vuex": "^4.5.6",
+ "@vue/cli-service": "^4.5.6",
+ "@vue/eslint-config-prettier": "^6.0.0",
+ "autoprefixer": "^10.0.1",
+ "babel-eslint": "^10.1.0",
+ "babel-plugin-dynamic-import-node": "^2.3.3",
+ "compression-webpack-plugin": "^6.0.2",
+ "eslint": "^7.10.0",
+ "eslint-plugin-prettier": "^3.1.4",
+ "eslint-plugin-vue": "^6.2.2",
+ "filemanager-webpack-plugin": "^2.0.5",
+ "husky": "^4.3.0",
+ "image-webpack-loader": "^7.0.1",
+ "increase-memory-limit": "^1.0.7",
+ "lint-staged": "^10.4.0",
+ "mockjs": "^1.1.0",
+ "plop": "^2.7.4",
+ "prettier": "^2.1.2",
+ "sass": "^1.26.11",
+ "sass-loader": "^10.0.2",
+ "script-loader": "^0.7.2",
+ "stylelint": "^13.7.2",
+ "stylelint-config-prettier": "^8.0.2",
+ "stylelint-config-recess-order": "^2.1.0",
+ "svg-sprite-loader": "^5.0.0",
+ "svgo": "^1.3.2",
+ "vue-template-compiler": "^2.6.12",
+ "webpackbar": "^4.0.0"
+ },
+ "keywords": [
+ "vue",
+ "admin",
+ "dashboard",
+ "element-ui",
+ "vue-admin",
+ "element-admin",
+ "boilerplate",
+ "admin-template",
+ "management-system"
+ ],
+ "engines": {
+ "node": ">=8.9",
+ "npm": ">= 3.0.0"
+ }
+}
diff --git a/plopfile.js b/plopfile.js
new file mode 100644
index 0000000..8fe16ee
--- /dev/null
+++ b/plopfile.js
@@ -0,0 +1,13 @@
+const viewGenerator = require("zx-templates/view/prompt");
+const curdGenerator = require("zx-templates/curd/prompt");
+const componentGenerator = require("zx-templates/component/prompt");
+const mockGenerator = require("zx-templates/mock/prompt");
+const vuexGenerator = require("zx-templates/vuex/prompt");
+
+module.exports = (plop) => {
+ plop.setGenerator("view", viewGenerator);
+ plop.setGenerator("curd", curdGenerator);
+ plop.setGenerator("component", componentGenerator);
+ plop.setGenerator("mock&api", mockGenerator);
+ plop.setGenerator("vuex", vuexGenerator);
+};
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 0000000..a7628ac
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,16 @@
+module.exports = {
+ printWidth: 80,
+ tabWidth: 2,
+ useTabs: false,
+ semi: true,
+ singleQuote: false,
+ quoteProps: "as-needed",
+ jsxSingleQuote: false,
+ trailingComma: "es5",
+ bracketSpacing: true,
+ jsxBracketSameLine: false,
+ arrowParens: "always",
+ htmlWhitespaceSensitivity: "ignore",
+ vueIndentScriptAndStyle: true,
+ endOfLine: "lf",
+};
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..7c31c49
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/favicon_backup.ico b/public/favicon_backup.ico
new file mode 100644
index 0000000..df36fcf
Binary files /dev/null and b/public/favicon_backup.ico differ
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..b876b3c
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ <%= VUE_APP_TITLE %>
+
+
+
+
+
+
+
+
+ 非常抱歉鉴于安全考量,您无法查看<%= VUE_APP_TITLE %>
+ 源代码,该系统基于vue-admin-beautiful开发
+
+
+
+
+
+
+
+
+
+
+
+
<%= VUE_APP_TITLE %>
+
+
+
+
+
diff --git a/public/static/css/loading.css b/public/static/css/loading.css
new file mode 100644
index 0000000..a7433cc
--- /dev/null
+++ b/public/static/css/loading.css
@@ -0,0 +1,96 @@
+.first-loading-wrp {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 90vh;
+ min-height: 90vh;
+}
+
+.first-loading-wrp > h1 {
+ font-size: 30px;
+ font-weight: bolder;
+}
+
+.first-loading-wrp .loading-wrp {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 98px;
+}
+
+.dot {
+ position: relative;
+ box-sizing: border-box;
+ display: inline-block;
+ width: 64px;
+ height: 64px;
+ font-size: 64px;
+ transform: rotate(45deg);
+ animation: antRotate 1.2s infinite linear;
+}
+
+.dot i {
+ position: absolute;
+ display: block;
+ width: 28px;
+ height: 28px;
+ background-color: #1890ff;
+ border-radius: 100%;
+ opacity: 0.3;
+ transform: scale(0.75);
+ transform-origin: 50% 50%;
+ animation: antSpinMove 1s infinite linear alternate;
+}
+
+.dot i:nth-child(1) {
+ top: 0;
+ left: 0;
+}
+
+.dot i:nth-child(2) {
+ top: 0;
+ right: 0;
+ -webkit-animation-delay: 0.4s;
+ animation-delay: 0.4s;
+}
+
+.dot i:nth-child(3) {
+ right: 0;
+ bottom: 0;
+ -webkit-animation-delay: 0.8s;
+ animation-delay: 0.8s;
+}
+
+.dot i:nth-child(4) {
+ bottom: 0;
+ left: 0;
+ -webkit-animation-delay: 1.2s;
+ animation-delay: 1.2s;
+}
+
+@keyframes antRotate {
+ to {
+ -webkit-transform: rotate(405deg);
+ transform: rotate(405deg);
+ }
+}
+
+@-webkit-keyframes antRotate {
+ to {
+ -webkit-transform: rotate(405deg);
+ transform: rotate(405deg);
+ }
+}
+
+@keyframes antSpinMove {
+ to {
+ opacity: 1;
+ }
+}
+
+@-webkit-keyframes antSpinMove {
+ to {
+ opacity: 1;
+ }
+}
diff --git a/push.sh b/push.sh
new file mode 100644
index 0000000..ab6163e
--- /dev/null
+++ b/push.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+set -e
+git init
+git add -A
+git commit -m '🎉🎉🎉仓库重置到2020年9月29日,Vue2.6最后一个版本,之前版本不再支持,具体请查阅文档,Vue 3.0版本即将发布请耐心等待!!!'
+git push -f "https://${access_token}@github.com/chuzhixin/vue-admin-beautiful.git" master
+exec /bin/bash
+
+
+
+
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..eb848ae
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/src/api/ad.js b/src/api/ad.js
new file mode 100644
index 0000000..cb8411e
--- /dev/null
+++ b/src/api/ad.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/ad/getList",
+ method: "get",
+ data,
+ });
+}
diff --git a/src/api/blacklist.js b/src/api/blacklist.js
new file mode 100644
index 0000000..41c7621
--- /dev/null
+++ b/src/api/blacklist.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/blacklist/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/changeLog.js b/src/api/changeLog.js
new file mode 100644
index 0000000..61936c7
--- /dev/null
+++ b/src/api/changeLog.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/changeLog/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/colorfulIcon.js b/src/api/colorfulIcon.js
new file mode 100644
index 0000000..1144767
--- /dev/null
+++ b/src/api/colorfulIcon.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getIconList(data) {
+ return request({
+ url: "/colorfulIcon/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/github.js b/src/api/github.js
new file mode 100644
index 0000000..f2e01a9
--- /dev/null
+++ b/src/api/github.js
@@ -0,0 +1,20 @@
+import request from "axios";
+
+export function getRepos(params) {
+ return request({
+ url: "https://api.github.com/repos/chuzhixin/vue-admin-beautiful",
+ method: "get",
+ params,
+ timeout: 10000,
+ });
+}
+
+export function getStargazers(params) {
+ return request({
+ url:
+ "https://api.github.com/repos/chuzhixin/vue-admin-beautiful/stargazers",
+ method: "get",
+ params,
+ timeout: 10000,
+ });
+}
diff --git a/src/api/goodsDetail.js b/src/api/goodsDetail.js
new file mode 100644
index 0000000..4540689
--- /dev/null
+++ b/src/api/goodsDetail.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/goodsDetail/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/goodsList.js b/src/api/goodsList.js
new file mode 100644
index 0000000..5bd5d28
--- /dev/null
+++ b/src/api/goodsList.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/goodsList/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/icon.js b/src/api/icon.js
new file mode 100644
index 0000000..ec62152
--- /dev/null
+++ b/src/api/icon.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getIconList(data) {
+ return request({
+ url: "/icon/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/markdown.js b/src/api/markdown.js
new file mode 100644
index 0000000..5197ec8
--- /dev/null
+++ b/src/api/markdown.js
@@ -0,0 +1,8 @@
+import request from "axios";
+
+export function getList() {
+ return request({
+ url: "https://cdn.jsdelivr.net/gh/prettier/prettier@master/docs/options.md",
+ method: "get",
+ });
+}
diff --git a/src/api/menuManagement.js b/src/api/menuManagement.js
new file mode 100644
index 0000000..c68d851
--- /dev/null
+++ b/src/api/menuManagement.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function getTree(data) {
+ return request({
+ url: "/menuManagement/getTree",
+ method: "post",
+ data,
+ });
+}
+
+export function doEdit(data) {
+ return request({
+ url: "/menuManagement/doEdit",
+ method: "post",
+ data,
+ });
+}
+
+export function doDelete(data) {
+ return request({
+ url: "/menuManagement/doDelete",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/notice.js b/src/api/notice.js
new file mode 100644
index 0000000..a528ebb
--- /dev/null
+++ b/src/api/notice.js
@@ -0,0 +1,8 @@
+import request from "@/utils/request";
+
+export function getNoticeList() {
+ return request({
+ url: "/notice/getList",
+ method: "post",
+ });
+}
diff --git a/src/api/personalCenter.js b/src/api/personalCenter.js
new file mode 100644
index 0000000..3626f68
--- /dev/null
+++ b/src/api/personalCenter.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/personalCenter/getList",
+ method: "post",
+ data,
+ });
+}
+
+export function doEdit(data) {
+ return request({
+ url: "/personalCenter/doEdit",
+ method: "post",
+ data,
+ });
+}
+
+export function doDelete(data) {
+ return request({
+ url: "/personalCenter/doDelete",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/publicKey.js b/src/api/publicKey.js
new file mode 100644
index 0000000..a4c1853
--- /dev/null
+++ b/src/api/publicKey.js
@@ -0,0 +1,8 @@
+import request from "@/utils/request";
+
+export function getPublicKey() {
+ return request({
+ url: "/publicKey",
+ method: "post",
+ });
+}
diff --git a/src/api/remixIcon.js b/src/api/remixIcon.js
new file mode 100644
index 0000000..5483110
--- /dev/null
+++ b/src/api/remixIcon.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getIconList(data) {
+ return request({
+ url: "/remixIcon/getList",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/roleManagement.js b/src/api/roleManagement.js
new file mode 100644
index 0000000..500645b
--- /dev/null
+++ b/src/api/roleManagement.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/roleManagement/getList",
+ method: "post",
+ data,
+ });
+}
+
+export function doEdit(data) {
+ return request({
+ url: "/roleManagement/doEdit",
+ method: "post",
+ data,
+ });
+}
+
+export function doDelete(data) {
+ return request({
+ url: "/roleManagement/doDelete",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/router.js b/src/api/router.js
new file mode 100644
index 0000000..563bfe3
--- /dev/null
+++ b/src/api/router.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getRouterList(data) {
+ return request({
+ url: "/menu/navigate",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/table.js b/src/api/table.js
new file mode 100644
index 0000000..5e60896
--- /dev/null
+++ b/src/api/table.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/table/getList",
+ method: "post",
+ data,
+ });
+}
+
+export function doEdit(data) {
+ return request({
+ url: "/table/doEdit",
+ method: "post",
+ data,
+ });
+}
+
+export function doDelete(data) {
+ return request({
+ url: "/table/doDelete",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/tree.js b/src/api/tree.js
new file mode 100644
index 0000000..471a49b
--- /dev/null
+++ b/src/api/tree.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getTreeList(data) {
+ return request({
+ url: "/tree/list",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/api/user.js b/src/api/user.js
new file mode 100644
index 0000000..9367d89
--- /dev/null
+++ b/src/api/user.js
@@ -0,0 +1,38 @@
+import request from "@/utils/request";
+import { encryptedData } from "@/utils/encrypt";
+import { loginRSA, tokenName } from "@/config/settings";
+
+export async function login(data) {
+ if (loginRSA) {
+ data = await encryptedData(data);
+ }
+ return request({
+ url: "/login",
+ method: "post",
+ data,
+ });
+}
+
+export function getUserInfo(accessToken) {
+ return request({
+ url: "/userInfo",
+ method: "post",
+ data: {
+ [tokenName]: accessToken,
+ },
+ });
+}
+
+export function logout() {
+ return request({
+ url: "/logout",
+ method: "post",
+ });
+}
+
+export function register() {
+ return request({
+ url: "/register",
+ method: "post",
+ });
+}
diff --git a/src/api/userManagement.js b/src/api/userManagement.js
new file mode 100644
index 0000000..ce923d6
--- /dev/null
+++ b/src/api/userManagement.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/userManagement/getList",
+ method: "post",
+ data,
+ });
+}
+
+export function doEdit(data) {
+ return request({
+ url: "/userManagement/doEdit",
+ method: "post",
+ data,
+ });
+}
+
+export function doDelete(data) {
+ return request({
+ url: "/userManagement/doDelete",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/assets/comparison/left.jpg b/src/assets/comparison/left.jpg
new file mode 100644
index 0000000..f5133cf
Binary files /dev/null and b/src/assets/comparison/left.jpg differ
diff --git a/src/assets/comparison/right.jpg b/src/assets/comparison/right.jpg
new file mode 100644
index 0000000..625a53f
Binary files /dev/null and b/src/assets/comparison/right.jpg differ
diff --git a/src/assets/error_images/401.png b/src/assets/error_images/401.png
new file mode 100644
index 0000000..90bbf6e
Binary files /dev/null and b/src/assets/error_images/401.png differ
diff --git a/src/assets/error_images/404.png b/src/assets/error_images/404.png
new file mode 100644
index 0000000..14fa725
Binary files /dev/null and b/src/assets/error_images/404.png differ
diff --git a/src/assets/error_images/cloud.png b/src/assets/error_images/cloud.png
new file mode 100644
index 0000000..247c06b
Binary files /dev/null and b/src/assets/error_images/cloud.png differ
diff --git a/src/assets/ewm.png b/src/assets/ewm.png
new file mode 100644
index 0000000..a97a6ad
Binary files /dev/null and b/src/assets/ewm.png differ
diff --git a/src/assets/login_images/background.jpg b/src/assets/login_images/background.jpg
new file mode 100644
index 0000000..87ac496
Binary files /dev/null and b/src/assets/login_images/background.jpg differ
diff --git a/src/assets/pro.png b/src/assets/pro.png
new file mode 100644
index 0000000..09bcef5
Binary files /dev/null and b/src/assets/pro.png differ
diff --git a/src/assets/qr_logo/lqr_logo.png b/src/assets/qr_logo/lqr_logo.png
new file mode 100644
index 0000000..f81db46
Binary files /dev/null and b/src/assets/qr_logo/lqr_logo.png differ
diff --git a/src/colorfulIcon/index.js b/src/colorfulIcon/index.js
new file mode 100644
index 0000000..245c2b2
--- /dev/null
+++ b/src/colorfulIcon/index.js
@@ -0,0 +1,17 @@
+import Vue from "vue";
+import { ColorfullIcon } from "@/layouts/components";
+
+Vue.component("vab-colorful-icon", ColorfullIcon);
+const req = require.context("./svg", false, /\.svg$/),
+ requireAll = (requireContext) => {
+ /*let a = requireContext.keys().map(requireContext);
+ let arr = [];
+ for (let i = 0; i < a.length; i++) {
+ console.log();
+ let icon = a[i].default.id;
+ arr.push(icon);
+ }
+ console.log(JSON.stringify(arr));*/
+ return requireContext.keys().map(requireContext);
+ };
+requireAll(req);
diff --git a/src/colorfulIcon/svg/alphabetical_sorting.svg b/src/colorfulIcon/svg/alphabetical_sorting.svg
new file mode 100644
index 0000000..3cfa035
--- /dev/null
+++ b/src/colorfulIcon/svg/alphabetical_sorting.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/colorfulIcon/svg/vab.svg b/src/colorfulIcon/svg/vab.svg
new file mode 100644
index 0000000..5c46271
--- /dev/null
+++ b/src/colorfulIcon/svg/vab.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/JsonEditor/index.vue b/src/components/JsonEditor/index.vue
new file mode 100644
index 0000000..f72dc51
--- /dev/null
+++ b/src/components/JsonEditor/index.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SelectTree/index.vue b/src/components/SelectTree/index.vue
new file mode 100644
index 0000000..6722eab
--- /dev/null
+++ b/src/components/SelectTree/index.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/VabCharge/index.vue b/src/components/VabCharge/index.vue
new file mode 100644
index 0000000..4ad52a0
--- /dev/null
+++ b/src/components/VabCharge/index.vue
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
diff --git a/src/components/VabImage/index.vue b/src/components/VabImage/index.vue
new file mode 100644
index 0000000..1a51db5
--- /dev/null
+++ b/src/components/VabImage/index.vue
@@ -0,0 +1,92 @@
+
+
+
+
+ {{ percent }}%
+
+
+
+
+
+
diff --git a/src/components/VabProfile/index.vue b/src/components/VabProfile/index.vue
new file mode 100644
index 0000000..038e8f8
--- /dev/null
+++ b/src/components/VabProfile/index.vue
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
diff --git a/src/components/VabQrCode/index.vue b/src/components/VabQrCode/index.vue
new file mode 100644
index 0000000..44820eb
--- /dev/null
+++ b/src/components/VabQrCode/index.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
diff --git a/src/components/VabSnow/index.vue b/src/components/VabSnow/index.vue
new file mode 100644
index 0000000..477c5c6
--- /dev/null
+++ b/src/components/VabSnow/index.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
diff --git a/src/components/VabSticky/index.vue b/src/components/VabSticky/index.vue
new file mode 100644
index 0000000..96a26a1
--- /dev/null
+++ b/src/components/VabSticky/index.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
diff --git a/src/components/VabUpload/index.vue b/src/components/VabUpload/index.vue
new file mode 100644
index 0000000..4032841
--- /dev/null
+++ b/src/components/VabUpload/index.vue
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/config/permission.js b/src/config/permission.js
new file mode 100644
index 0000000..2335558
--- /dev/null
+++ b/src/config/permission.js
@@ -0,0 +1,85 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 路由守卫,目前两种模式:all模式与intelligence模式
+ */
+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 "./settings";
+
+VabProgress.configure({
+ 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 (!loginInterception) hasToken = true;
+
+ if (hasToken) {
+ if (to.path === "/login") {
+ next({ path: "/" });
+ if (progressBar) VabProgress.done();
+ } else {
+ const hasPermissions =
+ store.getters["user/permissions"] &&
+ store.getters["user/permissions"].length > 0;
+ if (hasPermissions) {
+ next();
+ } else {
+ try {
+ let permissions;
+ if (!loginInterception) {
+ //settings.js loginInterception为false时,创建虚拟权限
+ await store.dispatch("user/setPermissions", ["admin"]);
+ permissions = ["admin"];
+ } else {
+ 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");
+ }
+ router.addRoutes(accessRoutes);
+ next({ ...to, replace: true });
+ } catch {
+ await store.dispatch("user/resetAccessToken");
+ if (progressBar) VabProgress.done();
+ }
+ }
+ }
+ } else {
+ if (routesWhiteList.indexOf(to.path) !== -1) {
+ next();
+ } else {
+ if (recordRoute) {
+ next(`/login?redirect=${to.path}`);
+ } else {
+ next("/login");
+ }
+
+ if (progressBar) VabProgress.done();
+ }
+ }
+ document.title = getPageTitle(to.meta.title);
+});
+router.afterEach(() => {
+ if (progressBar) VabProgress.done();
+});
diff --git a/src/config/settings.js b/src/config/settings.js
new file mode 100644
index 0000000..f237168
--- /dev/null
+++ b/src/config/settings.js
@@ -0,0 +1,101 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局变量配置
+ */
+module.exports = {
+ // 开发以及部署时的URL
+ publicPath: "",
+ // 生产环境构建文件的目录名
+ outputDir: "dist",
+ // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
+ assetsDir: "static",
+ // 开发环境每次保存时是否输出为eslint编译警告
+ lintOnSave: true,
+ // 进行编译的依赖
+ transpileDependencies: ["vue-echarts", "resize-detector", "zx-layouts"],
+ // 默认的接口地址 如果是开发环境和生产环境走vab-mock-server,当然你也可以选择自己配置成需要的接口地址
+ baseURL:
+ process.env.NODE_ENV === "development"
+ ? "vab-mock-server"
+ : "vab-mock-server",
+ //标题 (包括初次加载雪花屏的标题 页面的标题 浏览器的标题)
+ title: "vue-admin-beautiful",
+ //简写
+ abbreviation: "vab",
+ //开发环境端口号
+ devPort: "80",
+ //版本号
+ version: process.env.VUE_APP_VERSION,
+ //烦请保留package.json作者信息 保留版权可免费商用 如需去除并自定义为自己企业的版权请联系群主QQ 1204505056 需支付299元 恶意修改发生纠纷及出现任何问题 由修改人自行承担
+ copyright: process.env.VUE_APP_AUTHOR,
+ //是否显示页面底部版权信息,建议您显示,当然您也可以选择不显示,不管您是付费用户还是未付费用户您都有选择显示或者不显示的权利
+ footerCopyright: process.env.NODE_ENV !== "development",
+ //是否显示右上角github图标
+ githubCorner: process.env.NODE_ENV !== "development",
+ //是否显示顶部进度条
+ progressBar: true,
+ //缓存路由的最大数量
+ keepAliveMaxNum: 99,
+ // 路由模式,可选值为 history 或 hash
+ routerMode: "hash",
+ //不经过token校验的路由
+ routesWhiteList: ["/login", "/register", "/404", "/401"],
+ //加载时显示文字
+ loadingText: "正在加载中...",
+ //token名称
+ tokenName: "accessToken",
+ //token在localStorage、sessionStorage、cookie存储的key的名称
+ tokenTableName: "vue-admin-beautiful",
+ //token存储位置localStorage sessionStorage cookie
+ storage: "localStorage",
+ //token失效回退到登录页时是否记录本次的路由
+ recordRoute: true,
+ //是否显示logo,不显示时设置false,显示时请填写remixIcon图标名称,暂时只支持设置remixIcon
+ logo: "vuejs-fill",
+ //是否国定头部 固定fixed 不固定noFixed
+ header: "fixed",
+ //横纵布局 horizontal vertical
+ layout: "vertical",
+ //是否开启主题配置按钮
+ themeBar: true,
+ //是否显示多标签页
+ tagsBar: true,
+ //是否显示骨架屏
+ skeleton: false,
+ //配后端数据的接收方式application/json;charset=UTF-8或者application/x-www-form-urlencoded;charset=UTF-8
+ contentType: "application/json;charset=UTF-8",
+ //消息框消失时间
+ messageDuration: 3000,
+ //最长请求时间
+ requestTimeout: 5000,
+ //操作正常code,支持String、Array、int多种类型
+ successCode: [200, 0],
+ //登录失效code
+ invalidCode: 402,
+ //无权限code
+ noPermissionCode: 401,
+ //是否显示在页面高亮错误
+ errorLog: ["development", "test", "production"],
+ //是否开启登录拦截
+ loginInterception: true,
+ //是否开启登录RSA加密
+ loginRSA: true,
+ //是否依据mock数据生成webstorm HTTP Request请求文件
+ httpRequestFile: false,
+ //intelligence和all两种方式,前者后端权限只控制permissions不控制view文件的import(前后端配合,减轻后端工作量),all方式完全交给后端前端只负责加载
+ authentication: "intelligence",
+ //vertical布局时是否只保持一个子菜单的展开
+ uniqueOpened: true,
+ //vertical布局时默认展开的菜单path,使用逗号隔开建议只展开一个
+ defaultOopeneds: ["/vab"],
+ //需要加loading层的请求,防止重复提交
+ debounce: ["doEdit"],
+ //需要自动注入并加载的模块
+ providePlugin: { maptalks: "maptalks", "window.maptalks": "maptalks" },
+ //npm run build时是否自动生成7z压缩包
+ build7z: false,
+ //代码生成机生成在view下的文件夹名称
+ templateFolder: "project",
+ //是否显示终端donation打印
+ donation: true,
+};
diff --git a/src/config/static.js b/src/config/static.js
new file mode 100644
index 0000000..cec0521
--- /dev/null
+++ b/src/config/static.js
@@ -0,0 +1,53 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 导入所有 controller 模块,浏览器环境中自动输出controller文件夹下Mock接口,请勿修改。
+ */
+import Mock from "mockjs";
+import { paramObj } from "@/utils";
+
+const mocks = [];
+const files = require.context("../../mock/controller", false, /\.js$/);
+
+files.keys().forEach((key) => {
+ const obj = files(key);
+ mocks.push(...obj);
+});
+
+export function mockXHR() {
+ Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send;
+ Mock.XHR.prototype.send = function () {
+ if (this.custom.xhr) {
+ this.custom.xhr.withCredentials = this.withCredentials || false;
+
+ if (this.responseType) {
+ this.custom.xhr.responseType = this.responseType;
+ }
+ }
+ this.proxy_send(...arguments);
+ };
+
+ function XHR2ExpressReqWrap(respond) {
+ return function (options) {
+ let result = null;
+ if (respond instanceof Function) {
+ const { body, type, url } = options;
+ result = respond({
+ method: type,
+ body: JSON.parse(body),
+ query: paramObj(url),
+ });
+ } else {
+ result = respond;
+ }
+ return Mock.mock(result);
+ };
+ }
+
+ for (const i of mocks) {
+ Mock.mock(
+ new RegExp(i.url),
+ i.type || "get",
+ XHR2ExpressReqWrap(i.response)
+ );
+ }
+}
diff --git a/src/layouts/EmptyLayout.vue b/src/layouts/EmptyLayout.vue
new file mode 100644
index 0000000..98240ae
--- /dev/null
+++ b/src/layouts/EmptyLayout.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/layouts/components/Ad/index.vue b/src/layouts/components/Ad/index.vue
new file mode 100644
index 0000000..a5e2613
--- /dev/null
+++ b/src/layouts/components/Ad/index.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
diff --git a/src/layouts/components/index.js b/src/layouts/components/index.js
new file mode 100644
index 0000000..645619d
--- /dev/null
+++ b/src/layouts/components/index.js
@@ -0,0 +1,21 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 公共布局导出,已封装成npm,便于此后在线升级,当然也存在一定的弊端,给开发者自定义增加了一定的困难,如果您一定要进行高度自定义,请仔细阅读VIP群文档,layouts本地化篇
+ */
+export { default as ColorfullIcon } from "zx-layouts/ColorfullIcon";
+export { default as RemixIcon } from "zx-layouts/RemixIcon";
+export { default as VabDrag } from "zx-layouts/Drag";
+export { default as VabPermissions } from "zx-layouts/Permissions";
+export { default as VabQueryForm } from "zx-layouts/VabQueryForm/export";
+export { default as Logo } from "zx-layouts/Logo";
+export { default as Avatar } from "zx-layouts/Avatar";
+export { default as Ad } from "./Ad";
+export { default as AppMain } from "zx-layouts/AppMain";
+export { default as TagsBar } from "zx-layouts/TagsBar";
+export { default as SideBar } from "zx-layouts/SideBar";
+export { default as Breadcrumb } from "zx-layouts/Breadcrumb";
+export { default as FullScreenBar } from "zx-layouts/FullScreenBar";
+export { default as ErrorLog } from "zx-layouts/ErrorLog";
+export { default as ThemeBar } from "zx-layouts/ThemeBar";
+export { default as TopBar } from "zx-layouts/TopBar";
+export { default as NavBar } from "zx-layouts/NavBar";
diff --git a/src/layouts/index.vue b/src/layouts/index.vue
new file mode 100644
index 0000000..60b2ba7
--- /dev/null
+++ b/src/layouts/index.vue
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..b24ad78
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,23 @@
+import Vue from "vue";
+import App from "./App";
+import store from "./store";
+import router from "./router";
+import "./plugins";
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 生产环境默认都使用mock,如果正式用于生产环境时,记得去掉
+ */
+
+if (process.env.NODE_ENV === "production") {
+ const { mockXHR } = require("@/config/static");
+ mockXHR();
+}
+
+Vue.config.productionTip = false;
+
+new Vue({
+ el: "#vue-admin-beautiful",
+ router,
+ store,
+ render: (h) => h(App),
+});
diff --git a/src/plugins/echarts.js b/src/plugins/echarts.js
new file mode 100644
index 0000000..f35507e
--- /dev/null
+++ b/src/plugins/echarts.js
@@ -0,0 +1,11 @@
+import "echarts";
+import "echarts/map/js/china";
+import "echarts/map/js/world";
+
+import "echarts-wordcloud";
+
+import VabChart from "vue-echarts";
+import theme from "./vab-echarts-theme.json";
+
+VabChart.registerTheme("vab-echarts-theme", theme);
+export default VabChart;
diff --git a/src/plugins/element.js b/src/plugins/element.js
new file mode 100644
index 0000000..41226f1
--- /dev/null
+++ b/src/plugins/element.js
@@ -0,0 +1,9 @@
+import Vue from "vue";
+import ElementUI from "element-ui";
+import "element-ui/lib/theme-chalk/display.css";
+
+import "@/styles/element-variables.scss";
+
+Vue.use(ElementUI, {
+ size: "small",
+});
diff --git a/src/plugins/index.js b/src/plugins/index.js
new file mode 100644
index 0000000..19548e4
--- /dev/null
+++ b/src/plugins/index.js
@@ -0,0 +1,20 @@
+/* 公共引入,勿随意修改,修改时需经过确认 */
+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 Vab from "@/utils/vab";
+import { VabDrag, VabPermissions, VabQueryForm } from "@/layouts/components";
+import VabCount from "zx-count";
+
+Vue.use(Vab);
+Vue.use(VabPermissions);
+Vue.use(VabDrag);
+Vue.use(VabQueryForm);
+Vue.use(VabCount);
diff --git a/src/plugins/support.js b/src/plugins/support.js
new file mode 100644
index 0000000..0e6c2d0
--- /dev/null
+++ b/src/plugins/support.js
@@ -0,0 +1,21 @@
+import { MessageBox } from "element-ui";
+import { donation } from "@/config/settings";
+import { dependencies, repository } from "../../package.json";
+
+if (!!window.ActiveXObject || "ActiveXObject" in window) {
+ MessageBox({
+ title: "温馨提示",
+ message:
+ '自2015年3月起,微软已宣布弃用IE,且不再对IE提供任何更新维护,请点击此处 访问微软官网更新浏览器,如果您使用的是双核浏览器,请您切换浏览器内核为极速模式',
+ type: "warning",
+ showClose: false,
+ showConfirmButton: false,
+ closeOnClickModal: false,
+ closeOnPressEscape: false,
+ closeOnHashChange: false,
+ dangerouslyUseHTMLString: true,
+ });
+}
+if (!dependencies["zx-icon"] || !dependencies["zx-layouts"]) {
+ document.body.innerHTML = "";
+}
diff --git a/src/plugins/vab-echarts-theme.json b/src/plugins/vab-echarts-theme.json
new file mode 100644
index 0000000..86ba0db
--- /dev/null
+++ b/src/plugins/vab-echarts-theme.json
@@ -0,0 +1,452 @@
+{
+ "color": ["#1890FF", "#36CBCB", "#4ECB73", "#FBD437", "#F2637B", "#975FE5"],
+ "backgroundColor": "rgba(252,252,252,0)",
+ "textStyle": {},
+ "title": {
+ "textStyle": {
+ "color": "#666666"
+ },
+ "subtextStyle": {
+ "color": "#999999"
+ }
+ },
+ "line": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": "2"
+ }
+ },
+ "lineStyle": {
+ "normal": {
+ "width": "3"
+ }
+ },
+ "symbolSize": "8",
+ "symbol": "emptyCircle",
+ "smooth": false
+ },
+ "radar": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": "2"
+ }
+ },
+ "lineStyle": {
+ "normal": {
+ "width": "3"
+ }
+ },
+ "symbolSize": "8",
+ "symbol": "emptyCircle",
+ "smooth": false
+ },
+ "bar": {
+ "itemStyle": {
+ "normal": {
+ "barBorderWidth": 0,
+ "barBorderColor": "#ccc"
+ },
+ "emphasis": {
+ "barBorderWidth": 0,
+ "barBorderColor": "#ccc"
+ }
+ }
+ },
+ "pie": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "scatter": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "boxplot": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "parallel": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "sankey": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "funnel": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "gauge": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ },
+ "emphasis": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ }
+ },
+ "candlestick": {
+ "itemStyle": {
+ "normal": {
+ "color": "#e6a0d2",
+ "color0": "transparent",
+ "borderColor": "#e6a0d2",
+ "borderColor0": "#1890FF",
+ "borderWidth": "2"
+ }
+ }
+ },
+ "graph": {
+ "itemStyle": {
+ "normal": {
+ "borderWidth": 0,
+ "borderColor": "#ccc"
+ }
+ },
+ "lineStyle": {
+ "normal": {
+ "width": "1",
+ "color": "#cccccc"
+ }
+ },
+ "symbolSize": "8",
+ "symbol": "emptyCircle",
+ "smooth": false,
+ "color": ["#1890FF", "#36CBCB", "#4ECB73", "#FBD437", "#F2637B", "#975FE5"],
+ "label": {
+ "normal": {
+ "textStyle": {
+ "color": "#ffffff"
+ }
+ }
+ }
+ },
+ "map": {
+ "itemStyle": {
+ "normal": {
+ "areaColor": "#eeeeee",
+ "borderColor": "#aaaaaa",
+ "borderWidth": 0.5
+ },
+ "emphasis": {
+ "areaColor": "rgba(63,177,227,0.25)",
+ "borderColor": "#1890FF",
+ "borderWidth": 1
+ }
+ },
+ "label": {
+ "normal": {
+ "textStyle": {
+ "color": "#ffffff"
+ }
+ },
+ "emphasis": {
+ "textStyle": {
+ "color": "#1890FF"
+ }
+ }
+ }
+ },
+ "geo": {
+ "itemStyle": {
+ "normal": {
+ "areaColor": "#eeeeee",
+ "borderColor": "#aaaaaa",
+ "borderWidth": 0.5
+ },
+ "emphasis": {
+ "areaColor": "rgba(63,177,227,0.25)",
+ "borderColor": "#1890FF",
+ "borderWidth": 1
+ }
+ },
+ "label": {
+ "normal": {
+ "textStyle": {
+ "color": "#ffffff"
+ }
+ },
+ "emphasis": {
+ "textStyle": {
+ "color": "#1890FF"
+ }
+ }
+ }
+ },
+ "categoryAxis": {
+ "axisLine": {
+ "show": true,
+ "lineStyle": {
+ "color": "#cccccc"
+ }
+ },
+ "axisTick": {
+ "show": false,
+ "lineStyle": {
+ "color": "#333"
+ }
+ },
+ "axisLabel": {
+ "show": true,
+ "textStyle": {
+ "color": "#999999"
+ }
+ },
+ "splitLine": {
+ "show": true,
+ "lineStyle": {
+ "color": ["#eeeeee"]
+ }
+ },
+ "splitArea": {
+ "show": false,
+ "areaStyle": {
+ "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
+ }
+ }
+ },
+ "valueAxis": {
+ "axisLine": {
+ "show": true,
+ "lineStyle": {
+ "color": "#cccccc"
+ }
+ },
+ "axisTick": {
+ "show": true,
+ "lineStyle": {
+ "color": "#cccccc"
+ }
+ },
+ "axisLabel": {
+ "show": true,
+ "textStyle": {
+ "color": "#999999"
+ }
+ },
+ "splitLine": {
+ "show": true,
+ "lineStyle": {
+ "color": ["#eeeeee"]
+ }
+ },
+ "splitArea": {
+ "show": false,
+ "areaStyle": {
+ "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
+ }
+ }
+ },
+ "logAxis": {
+ "axisLine": {
+ "show": true,
+ "lineStyle": {
+ "color": "#cccccc"
+ }
+ },
+ "axisTick": {
+ "show": false,
+ "lineStyle": {
+ "color": "#333"
+ }
+ },
+ "axisLabel": {
+ "show": true,
+ "textStyle": {
+ "color": "#999999"
+ }
+ },
+ "splitLine": {
+ "show": true,
+ "lineStyle": {
+ "color": ["#eeeeee"]
+ }
+ },
+ "splitArea": {
+ "show": false,
+ "areaStyle": {
+ "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
+ }
+ }
+ },
+ "timeAxis": {
+ "axisLine": {
+ "show": true,
+ "lineStyle": {
+ "color": "#cccccc"
+ }
+ },
+ "axisTick": {
+ "show": false,
+ "lineStyle": {
+ "color": "#333"
+ }
+ },
+ "axisLabel": {
+ "show": true,
+ "textStyle": {
+ "color": "#999999"
+ }
+ },
+ "splitLine": {
+ "show": true,
+ "lineStyle": {
+ "color": ["#eeeeee"]
+ }
+ },
+ "splitArea": {
+ "show": false,
+ "areaStyle": {
+ "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
+ }
+ }
+ },
+ "toolbox": {
+ "iconStyle": {
+ "normal": {
+ "borderColor": "#999999"
+ },
+ "emphasis": {
+ "borderColor": "#666666"
+ }
+ }
+ },
+ "legend": {
+ "textStyle": {
+ "color": "#999999"
+ }
+ },
+ "tooltip": {
+ "axisPointer": {
+ "lineStyle": {
+ "color": "#ffffff",
+ "width": 1
+ },
+ "crossStyle": {
+ "color": "#ffffff",
+ "width": 1
+ }
+ }
+ },
+ "timeline": {
+ "lineStyle": {
+ "color": "#4ECB73",
+ "width": 1
+ },
+ "itemStyle": {
+ "normal": {
+ "color": "#4ECB73",
+ "borderWidth": 1
+ },
+ "emphasis": {
+ "color": "#4ECB73"
+ }
+ },
+ "controlStyle": {
+ "normal": {
+ "color": "#4ECB73",
+ "borderColor": "#4ECB73",
+ "borderWidth": 0.5
+ },
+ "emphasis": {
+ "color": "#4ECB73",
+ "borderColor": "#4ECB73",
+ "borderWidth": 0.5
+ }
+ },
+ "checkpointStyle": {
+ "color": "#1890FF",
+ "borderColor": "rgba(63,177,227,0.15)"
+ },
+ "label": {
+ "normal": {
+ "textStyle": {
+ "color": "#4ECB73"
+ }
+ },
+ "emphasis": {
+ "textStyle": {
+ "color": "#4ECB73"
+ }
+ }
+ }
+ },
+ "visualMap": {
+ "color": ["#1890FF", "#afe8ff"]
+ },
+ "dataZoom": {
+ "backgroundColor": "rgba(255,255,255,0)",
+ "dataBackgroundColor": "rgba(222,222,222,1)",
+ "fillerColor": "rgba(114,230,212,0.25)",
+ "handleColor": "#cccccc",
+ "handleSize": "100%",
+ "textStyle": {
+ "color": "#999999"
+ }
+ },
+ "markPoint": {
+ "label": {
+ "normal": {
+ "textStyle": {
+ "color": "#ffffff"
+ }
+ },
+ "emphasis": {
+ "textStyle": {
+ "color": "#ffffff"
+ }
+ }
+ }
+ }
+}
diff --git a/src/plugins/vabComparison.js b/src/plugins/vabComparison.js
new file mode 100644
index 0000000..a969dc6
--- /dev/null
+++ b/src/plugins/vabComparison.js
@@ -0,0 +1,3 @@
+import VabComparison from "zx-comparison";
+
+export default VabComparison;
diff --git a/src/plugins/vabIcon.js b/src/plugins/vabIcon.js
new file mode 100644
index 0000000..1052605
--- /dev/null
+++ b/src/plugins/vabIcon.js
@@ -0,0 +1,4 @@
+import Vue from "vue";
+import VabIcon from "zx-icon";
+
+Vue.component("vab-icon", VabIcon);
diff --git a/src/plugins/vabKeel.js b/src/plugins/vabKeel.js
new file mode 100644
index 0000000..a9a9015
--- /dev/null
+++ b/src/plugins/vabKeel.js
@@ -0,0 +1,8 @@
+import { Heading, Img, Keel, Text } from "zx-keel";
+import "zx-keel/dist/zx-keel.css";
+
+const VabKeel = Keel;
+const VabKeelHeading = Heading;
+const VabKeelImg = Img;
+const VabKeelText = Text;
+export { VabKeel, VabKeelHeading, VabKeelImg, VabKeelText };
diff --git a/src/plugins/vabMagnifier.js b/src/plugins/vabMagnifier.js
new file mode 100644
index 0000000..d2904a5
--- /dev/null
+++ b/src/plugins/vabMagnifier.js
@@ -0,0 +1,3 @@
+import VabMagnifier from "zx-magnifie";
+
+export default VabMagnifier;
diff --git a/src/plugins/vabMarkdownEditor.js b/src/plugins/vabMarkdownEditor.js
new file mode 100644
index 0000000..bfa51a8
--- /dev/null
+++ b/src/plugins/vabMarkdownEditor.js
@@ -0,0 +1,5 @@
+import ZxMarkdownEditor from "zx-markdown-editor";
+import "zx-markdown-editor/dist/zx-markdown-editor.css";
+
+const VabMarkdownEditor = ZxMarkdownEditor;
+export default VabMarkdownEditor;
diff --git a/src/plugins/vabPlayer.js b/src/plugins/vabPlayer.js
new file mode 100644
index 0000000..a670976
--- /dev/null
+++ b/src/plugins/vabPlayer.js
@@ -0,0 +1,7 @@
+import { Custom, Flv, Hls, Mp4 } from "zx-player";
+
+const VabPlayerMp4 = Mp4;
+const VabPlayerHls = Hls;
+const VabPlayerFlv = Flv;
+const VabPlayerCustom = Custom;
+export { VabPlayerMp4, VabPlayerHls, VabPlayerFlv, VabPlayerCustom };
diff --git a/src/plugins/vabQuill.js b/src/plugins/vabQuill.js
new file mode 100644
index 0000000..61c2902
--- /dev/null
+++ b/src/plugins/vabQuill.js
@@ -0,0 +1,4 @@
+import "zx-quill/dist/zx-quill.css";
+import VabQuill from "zx-quill";
+
+export default VabQuill;
diff --git a/src/plugins/vabVerify.js b/src/plugins/vabVerify.js
new file mode 100644
index 0000000..88fb9fd
--- /dev/null
+++ b/src/plugins/vabVerify.js
@@ -0,0 +1,4 @@
+import VabVerify from "zx-verify";
+import "zx-verify/dist/zx-verify.css";
+
+export default VabVerify;
diff --git a/src/remixIcon/index.js b/src/remixIcon/index.js
new file mode 100644
index 0000000..df0ab19
--- /dev/null
+++ b/src/remixIcon/index.js
@@ -0,0 +1,17 @@
+import Vue from "vue";
+import { RemixIcon } from "@/layouts/components";
+
+Vue.component("vab-remix-icon", RemixIcon);
+const req = require.context("./svg", false, /\.svg$/),
+ requireAll = (requireContext) => {
+ /*let a = requireContext.keys().map(requireContext);
+ let arr = [];
+ for (let i = 0; i < a.length; i++) {
+ console.log();
+ let icon = a[i].default.id;
+ arr.push(icon);
+ }
+ console.log(JSON.stringify(arr));*/
+ return requireContext.keys().map(requireContext);
+ };
+requireAll(req);
diff --git a/src/remixIcon/svg/qq-fill.svg b/src/remixIcon/svg/qq-fill.svg
new file mode 100644
index 0000000..1f446b1
--- /dev/null
+++ b/src/remixIcon/svg/qq-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/remixIcon/svg/vuejs-fill.svg b/src/remixIcon/svg/vuejs-fill.svg
new file mode 100644
index 0000000..1b1a137
--- /dev/null
+++ b/src/remixIcon/svg/vuejs-fill.svg
@@ -0,0 +1 @@
+
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..7efa1c6
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,497 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description router全局配置,如有必要可分文件抽离,其中asyncRoutes只有在intelligence模式下才会用到,vip文档中已提供路由的基础图标与小清新图标的配置方案,请仔细阅读
+ */
+
+import Vue from "vue";
+import VueRouter from "vue-router";
+import Layout from "@/layouts";
+import EmptyLayout from "@/layouts/EmptyLayout";
+import { publicPath, routerMode } from "@/config/settings";
+
+Vue.use(VueRouter);
+export const constantRoutes = [
+ {
+ path: "/login",
+ component: () => import("@/views/login/index"),
+ hidden: true,
+ },
+ {
+ path: "/register",
+ component: () => import("@/views/register/index"),
+ hidden: true,
+ },
+ {
+ path: "/401",
+ name: "401",
+ component: () => import("@/views/401"),
+ hidden: true,
+ },
+ {
+ path: "/404",
+ name: "404",
+ component: () => import("@/views/404"),
+ hidden: true,
+ },
+];
+
+export const asyncRoutes = [
+ {
+ path: "/",
+ component: Layout,
+ redirect: "index",
+ children: [
+ {
+ path: "index",
+ name: "Index",
+ component: () => import("@/views/index/index"),
+ meta: {
+ title: "首页",
+ icon: "home",
+ affix: true,
+ },
+ },
+ ],
+ },
+ {
+ path: "/personalCenter",
+ component: Layout,
+ hidden: true,
+ redirect: "personalCenter",
+ children: [
+ {
+ path: "personalCenter",
+ name: "PersonalCenter",
+ component: () => import("@/views/personalCenter/index"),
+ meta: {
+ title: "个人中心",
+ },
+ },
+ ],
+ },
+ /* {
+ path: "/test",
+ component: Layout,
+ redirect: "noRedirect",
+ children: [
+ {
+ path: "test",
+ name: "Test",
+ component: () => import("@/views/test/index"),
+ meta: {
+ title: "test",
+ icon: "marker",
+ permissions: ["admin"],
+ },
+ },
+ ],
+ }, */
+ {
+ path: "/personnelManagement",
+ component: Layout,
+ redirect: "noRedirect",
+ name: "PersonnelManagement",
+ meta: { title: "配置", icon: "users-cog", permissions: ["admin"] },
+ children: [
+ {
+ path: "userManagement",
+ name: "UserManagement",
+ component: () =>
+ import("@/views/personnelManagement/userManagement/index"),
+ meta: { title: "用户管理" },
+ },
+ {
+ path: "roleManagement",
+ name: "RoleManagement",
+ component: () =>
+ import("@/views/personnelManagement/roleManagement/index"),
+ meta: { title: "角色管理" },
+ },
+ {
+ path: "menuManagement",
+ name: "MenuManagement",
+ component: () =>
+ import("@/views/personnelManagement/menuManagement/index"),
+ meta: { title: "菜单管理", badge: "New" },
+ },
+ ],
+ },
+ {
+ path: "/vab",
+ component: Layout,
+ redirect: "noRedirect",
+ name: "Vab",
+ alwaysShow: true,
+ meta: { title: "组件", icon: "box-open" },
+ children: [
+ {
+ path:
+ "https://github.com/chuzhixin/vue-admin-beautiful?utm_source=gold_browser_extension",
+ name: "ExternalLink",
+ meta: {
+ title: "外链",
+ target: "_blank",
+ permissions: ["admin", "editor"],
+ badge: "New",
+ },
+ },
+ {
+ path: "permissions",
+ name: "Permission",
+ component: () => import("@/views/vab/permissions/index"),
+ meta: {
+ title: "权限控制",
+ permissions: ["admin", "editor"],
+ },
+ },
+ {
+ path: "icon",
+ component: EmptyLayout,
+ redirect: "noRedirect",
+ name: "Icon",
+ meta: {
+ title: "图标",
+ permissions: ["admin"],
+ },
+ children: [
+ {
+ path: "awesomeIcon",
+ name: "AwesomeIcon",
+ component: () => import("@/views/vab/icon/index"),
+ meta: { title: "常规图标" },
+ },
+ {
+ path: "remixIcon",
+ name: "RemixIcon",
+ component: () => import("@/views/vab/icon/remixIcon"),
+ meta: { title: "小清新图标" },
+ },
+ {
+ path: "colorfulIcon",
+ name: "ColorfulIcon",
+ component: () => import("@/views/vab/icon/colorfulIcon"),
+ meta: { title: "多彩图标" },
+ },
+ ],
+ },
+ {
+ path: "table",
+ component: EmptyLayout,
+ redirect: "noRedirect",
+ name: "Table",
+ meta: {
+ title: "表格",
+ permissions: ["admin"],
+ },
+ children: [
+ {
+ path: "comprehensiveTable",
+ name: "ComprehensiveTable",
+ component: () => import("@/views/vab/table/index"),
+ meta: { title: "综合表格" },
+ },
+ {
+ path: "inlineEditTable",
+ name: "InlineEditTable",
+ component: () => import("@/views/vab/table/inlineEditTable"),
+ meta: { title: "行内编辑" },
+ },
+ ],
+ },
+ {
+ path: "map",
+ component: () => import("@/views/vab/map/index"),
+ name: "Map",
+ meta: {
+ title: "地图",
+ permissions: ["admin"],
+ },
+ },
+
+ {
+ path: "webSocket",
+ name: "WebSocket",
+ component: () => import("@/views/vab/webSocket/index"),
+ meta: { title: "webSocket", permissions: ["admin"] },
+ },
+ {
+ path: "form",
+ name: "Form",
+ component: () => import("@/views/vab/form/index"),
+ meta: { title: "表单", permissions: ["admin"] },
+ },
+ {
+ path: "element",
+ name: "Element",
+ component: () => import("@/views/vab/element/index"),
+ meta: { title: "常用组件", permissions: ["admin"] },
+ },
+ {
+ path: "tree",
+ name: "Tree",
+ component: () => import("@/views/vab/tree/index"),
+ meta: { title: "树", permissions: ["admin"] },
+ },
+ {
+ path: "card",
+ name: "Card",
+ component: () => import("@/views/vab/card/index"),
+ meta: { title: "卡片", permissions: ["admin"] },
+ },
+
+ {
+ path: "betterScroll",
+ name: "BetterScroll",
+ component: () => import("@/views/vab/betterScroll/index"),
+ meta: {
+ title: "滚动侦测",
+ permissions: ["admin"],
+ },
+ },
+ {
+ path: "verify",
+ name: "Verify",
+ component: () => import("@/views/vab/verify/index"),
+ meta: { title: "验证码", permissions: ["admin"] },
+ },
+ {
+ path: "menu1",
+ component: () => import("@/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: () => import("@/views/vab/nested/menu1/menu1-1/index"),
+
+ children: [
+ {
+ path: "menu1-1-1",
+ name: "Menu1-1-1",
+ meta: { title: "嵌套路由 1-1-1" },
+ component: () =>
+ import("@/views/vab/nested/menu1/menu1-1/menu1-1-1/index"),
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "magnifier",
+ name: "Magnifier",
+ component: () => import("@/views/vab/magnifier/index"),
+ meta: { title: "放大镜", permissions: ["admin"] },
+ },
+ {
+ path: "echarts",
+ name: "Echarts",
+ component: () => import("@/views/vab/echarts/index"),
+ meta: { title: "图表", permissions: ["admin"] },
+ },
+
+ {
+ path: "loading",
+ name: "Loading",
+ component: () => import("@/views/vab/loading/index"),
+ meta: { title: "loading", permissions: ["admin"] },
+ },
+ {
+ path: "player",
+ name: "Player",
+ component: () => import("@/views/vab/player/index"),
+ meta: { title: "视频播放器", permissions: ["admin"] },
+ },
+ {
+ path: "markdownEditor",
+ name: "MarkdownEditor",
+ component: () => import("@/views/vab/markdownEditor/index"),
+ meta: { title: "markdown编辑器", permissions: ["admin"] },
+ },
+ {
+ path: "editor",
+ name: "Editor",
+ component: () => import("@/views/vab/editor/index"),
+ meta: {
+ title: "富文本编辑器",
+ permissions: ["admin"],
+ badge: "New",
+ },
+ },
+ {
+ path: "qrCode",
+ name: "QrCode",
+ component: () => import("@/views/vab/qrCode/index"),
+ meta: { title: "二维码", permissions: ["admin"] },
+ },
+ {
+ path: "backToTop",
+ name: "BackToTop",
+ component: () => import("@/views/vab/backToTop/index"),
+ meta: { title: "返回顶部", permissions: ["admin"] },
+ },
+ {
+ path: "lodash",
+ name: "Lodash",
+ component: () => import("@/views/vab/lodash/index"),
+ meta: { title: "lodash", permissions: ["admin"] },
+ },
+ {
+ path: "imgComparison",
+ name: "ImgComparison",
+ component: () => import("@/views/vab/imgComparison/index"),
+ meta: { title: "图像拖拽比对", permissions: ["admin"] },
+ },
+ {
+ path: "codeGenerator",
+ name: "CodeGenerator",
+ component: () => import("@/views/vab/codeGenerator/index"),
+ meta: { title: "代码生成机", permissions: ["admin"] },
+ },
+ {
+ path: "markdown",
+ name: "Markdown",
+ component: () => import("@/views/vab/markdown/index"),
+ meta: { title: "markdown阅读器", permissions: ["admin"] },
+ },
+ {
+ path: "smallComponents",
+ name: "SmallComponents",
+ component: () => import("@/views/vab/smallComponents/index"),
+ meta: { title: "小组件", permissions: ["admin"] },
+ },
+
+ {
+ path: "upload",
+ name: "Upload",
+ component: () => import("@/views/vab/upload/index"),
+ meta: { title: "上传", permissions: ["admin"] },
+ },
+ {
+ path: "sticky",
+ name: "Sticky",
+ component: () => import("@/views/vab/sticky/index"),
+ meta: { title: "sticky吸附", permissions: ["admin"] },
+ },
+ {
+ path: "log",
+ name: "Log",
+ component: () => import("@/views/vab/errorLog/index"),
+ meta: { title: "错误日志模拟", permissions: ["admin"] },
+ },
+ {
+ path: "more",
+ name: "More",
+ component: () => import("@/views/vab/more/index"),
+ meta: { title: "更多组件", permissions: ["admin"] },
+ },
+ {
+ path: "blacklist",
+ name: "Blacklist",
+ component: () => import("@/views/vab/blacklist/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: () => import("@/views/mall/pay/index"),
+ meta: {
+ title: "支付",
+ noKeepAlive: true,
+ },
+ children: null,
+ },
+ {
+ path: "goodsList",
+ name: "GoodsList",
+ component: () => import("@/views/mall/goodsList/index"),
+ meta: {
+ title: "商品列表",
+ },
+ },
+ {
+ path: "goodsDetail",
+ name: "GoodsDetail",
+ component: () => import("@/views/mall/goodsDetail/index"),
+ meta: {
+ title: "商品详情",
+ },
+ },
+ ],
+ },
+ {
+ path: "/error",
+ component: EmptyLayout,
+ redirect: "noRedirect",
+ name: "Error",
+ meta: { title: "错误页", icon: "bug" },
+ children: [
+ {
+ path: "401",
+ name: "Error401",
+ component: () => import("@/views/401"),
+ meta: { title: "401" },
+ },
+ {
+ path: "404",
+ name: "Error404",
+ component: () => import("@/views/404"),
+ meta: { title: "404" },
+ },
+ ],
+ },
+ {
+ path: "*",
+ redirect: "/404",
+ hidden: true,
+ },
+];
+
+const router = new VueRouter({
+ base: publicPath,
+ mode: routerMode,
+ scrollBehavior: () => ({
+ y: 0,
+ }),
+ routes: constantRoutes,
+});
+//注释的地方是允许路由重复点击,如果你觉得框架路由跳转规范太过严格可选择放开
+/* const originalPush = VueRouter.prototype.push;
+VueRouter.prototype.push = function push(location, onResolve, onReject) {
+ if (onResolve || onReject)
+ return originalPush.call(this, location, onResolve, onReject);
+ return originalPush.call(this, location).catch((err) => err);
+}; */
+
+export function resetRouter() {
+ router.matcher = new VueRouter({
+ base: publicPath,
+ mode: routerMode,
+ scrollBehavior: () => ({
+ y: 0,
+ }),
+ routes: constantRoutes,
+ }).matcher;
+}
+
+export default router;
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..e89e911
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,22 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 导入所有 vuex 模块,自动加入namespaced:true,用于解决vuex命名冲突,请勿修改。
+ */
+
+import Vue from "vue";
+import Vuex from "vuex";
+
+Vue.use(Vuex);
+const files = require.context("./modules", false, /\.js$/);
+const modules = {};
+
+files.keys().forEach((key) => {
+ modules[key.replace(/(\.\/|\.js)/g, "")] = files(key).default;
+});
+Object.keys(modules).forEach((key) => {
+ modules[key]["namespaced"] = true;
+});
+const store = new Vuex.Store({
+ modules,
+});
+export default store;
diff --git a/src/store/modules/errorLog.js b/src/store/modules/errorLog.js
new file mode 100644
index 0000000..62f1e4d
--- /dev/null
+++ b/src/store/modules/errorLog.js
@@ -0,0 +1,26 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 异常捕获的状态拦截,请勿修改
+ */
+
+const state = { errorLogs: [] };
+const getters = {
+ errorLogs: (state) => state.errorLogs,
+};
+const mutations = {
+ addErrorLog(state, errorLog) {
+ state.errorLogs.push(errorLog);
+ },
+ clearErrorLog: (state) => {
+ state.errorLogs.splice(0);
+ },
+};
+const actions = {
+ addErrorLog({ commit }, errorLog) {
+ commit("addErrorLog", errorLog);
+ },
+ clearErrorLog({ commit }) {
+ commit("clearErrorLog");
+ },
+};
+export default { state, getters, mutations, actions };
diff --git a/src/store/modules/routes.js b/src/store/modules/routes.js
new file mode 100644
index 0000000..5003261
--- /dev/null
+++ b/src/store/modules/routes.js
@@ -0,0 +1,47 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 路由拦截状态管理,目前两种模式:all模式与intelligence模式,其中partialRoutes是菜单暂未使用
+ */
+import { asyncRoutes, constantRoutes } from "@/router";
+import { getRouterList } from "@/api/router";
+import { filterAllRoutes, 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);
+ },
+ setAllRoutes(state, routes) {
+ state.routes = constantRoutes.concat(routes);
+ },
+ setPartialRoutes(state, routes) {
+ state.partialRoutes = constantRoutes.concat(routes);
+ },
+};
+const actions = {
+ async setRoutes({ commit }, permissions) {
+ //开源版只过滤动态路由permissions,admin不再默认拥有全部权限
+ const finallyAsyncRoutes = await filterAsyncRoutes(
+ [...asyncRoutes],
+ permissions
+ );
+ commit("setRoutes", finallyAsyncRoutes);
+ return finallyAsyncRoutes;
+ },
+ async setAllRoutes({ commit }) {
+ let { data } = await getRouterList();
+ data.push({ path: "*", redirect: "/404", hidden: true });
+ let accessRoutes = filterAllRoutes(data);
+ commit("setAllRoutes", accessRoutes);
+ return accessRoutes;
+ },
+ setPartialRoutes({ commit }, accessRoutes) {
+ commit("setPartialRoutes", accessRoutes);
+ return accessRoutes;
+ },
+};
+export default { state, getters, mutations, actions };
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
new file mode 100644
index 0000000..a4d4fa9
--- /dev/null
+++ b/src/store/modules/settings.js
@@ -0,0 +1,77 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 所有全局配置的状态管理,如无必要请勿修改
+ */
+
+import defaultSettings from "@/config/settings";
+
+const { tagsBar, logo, layout, header, themeBar, skeleton } = defaultSettings;
+const theme =
+ JSON.parse(localStorage.getItem("vue-admin-beautiful-theme")) || "";
+const state = {
+ tagsBar: theme.tagsBar || tagsBar,
+ logo,
+ collapse: false,
+ layout: theme.layout || layout,
+ header: theme.header || header,
+ skeleton,
+ device: "desktop",
+ themeBar,
+};
+const getters = {
+ collapse: (state) => state.collapse,
+ device: (state) => state.device,
+ header: (state) => state.header,
+ layout: (state) => state.layout,
+ logo: (state) => state.logo,
+ tagsBar: (state) => state.tagsBar,
+ themeBar: (state) => state.themeBar,
+ skeleton: (state) => state.skeleton,
+};
+const mutations = {
+ changeLayout: (state, layout) => {
+ if (layout) state.layout = layout;
+ },
+ changeHeader: (state, header) => {
+ if (header) state.header = header;
+ },
+ changeTagsBar: (state, tagsBar) => {
+ if (tagsBar) state.tagsBar = tagsBar;
+ },
+ changeCollapse: (state) => {
+ state.collapse = !state.collapse;
+ },
+ foldSideBar: (state) => {
+ state.collapse = true;
+ },
+ openSideBar: (state) => {
+ state.collapse = false;
+ },
+ toggleDevice: (state, device) => {
+ state.device = device;
+ },
+};
+const actions = {
+ changeLayout({ commit }, layout) {
+ commit("changeLayout", layout);
+ },
+ changeHeader({ commit }, header) {
+ commit("changeHeader", header);
+ },
+ changeTagsBar({ commit }, tagsBar) {
+ commit("changeTagsBar", tagsBar);
+ },
+ changeCollapse({ commit }) {
+ commit("changeCollapse");
+ },
+ foldSideBar({ commit }) {
+ commit("foldSideBar");
+ },
+ openSideBar({ commit }) {
+ commit("openSideBar");
+ },
+ toggleDevice({ commit }, device) {
+ commit("toggleDevice", device);
+ },
+};
+export default { state, getters, mutations, actions };
diff --git a/src/store/modules/table.js b/src/store/modules/table.js
new file mode 100644
index 0000000..8ef3625
--- /dev/null
+++ b/src/store/modules/table.js
@@ -0,0 +1,21 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 代码生成机状态管理
+ */
+
+const state = { srcCode: "" };
+const getters = {
+ srcTableCode: (state) => state.srcCode,
+};
+
+const mutations = {
+ setTableCode(state, srcCode) {
+ state.srcCode = srcCode;
+ },
+};
+const actions = {
+ setTableCode({ commit }, srcCode) {
+ commit("setTableCode", srcCode);
+ },
+};
+export default { state, getters, mutations, actions };
diff --git a/src/store/modules/tagsBar.js b/src/store/modules/tagsBar.js
new file mode 100644
index 0000000..067d933
--- /dev/null
+++ b/src/store/modules/tagsBar.js
@@ -0,0 +1,116 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description tagsBar多标签页逻辑,前期借鉴了很多开源项目发现都有个共同的特点很繁琐并不符合框架设计的初衷,后来在github用户cyea的启发下完成了重构,请勿修改
+ */
+
+const state = {
+ visitedRoutes: [],
+};
+const getters = {
+ visitedRoutes: (state) => state.visitedRoutes,
+};
+const mutations = {
+ addVisitedRoute(state, route) {
+ if (state.visitedRoutes.some((item) => item.path === route.path)) return;
+ state.visitedRoutes.push(Object.assign({}, route));
+ },
+ delVisitedRoute(state, route) {
+ state.visitedRoutes.forEach((item, index) => {
+ if (item.path === route.path) {
+ state.visitedRoutes.splice(index, 1);
+ }
+ });
+ },
+ delOthersVisitedRoute(state, route) {
+ state.visitedRoutes = state.visitedRoutes.filter((item) => {
+ return item.meta.affix || item.path === route.path;
+ });
+ },
+ delLeftVisitedRoute(state, route) {
+ let index = state.visitedRoutes.length;
+ state.visitedRoutes = state.visitedRoutes.filter((item) => {
+ if (item.name === route.name) {
+ index = state.visitedRoutes.indexOf(item);
+ }
+ return item.meta.affix || index <= state.visitedRoutes.indexOf(item);
+ });
+ },
+ delRightVisitedRoute(state, route) {
+ let index = state.visitedRoutes.length;
+ state.visitedRoutes = state.visitedRoutes.filter((item) => {
+ if (item.name === route.name) {
+ index = state.visitedRoutes.indexOf(item);
+ }
+ return item.meta.affix || index >= state.visitedRoutes.indexOf(item);
+ });
+ },
+ delAllVisitedRoutes(state) {
+ state.visitedRoutes = state.visitedRoutes.filter((item) => item.meta.affix);
+ },
+ updateVisitedRoute(state, route) {
+ state.visitedRoutes.forEach((item) => {
+ if (item.path === route.path) {
+ item = Object.assign(item, route);
+ }
+ });
+ },
+};
+const actions = {
+ addVisitedRoute({ commit }, route) {
+ commit("addVisitedRoute", route);
+ },
+ async delRoute({ dispatch, state }, route) {
+ await dispatch("delVisitedRoute", route);
+ return {
+ visitedRoutes: [...state.visitedRoutes],
+ };
+ },
+ delVisitedRoute({ commit, state }, route) {
+ commit("delVisitedRoute", route);
+ return [...state.visitedRoutes];
+ },
+ async delOthersRoutes({ dispatch, state }, route) {
+ await dispatch("delOthersVisitedRoute", route);
+ return {
+ visitedRoutes: [...state.visitedRoutes],
+ };
+ },
+ async delLeftRoutes({ dispatch, state }, route) {
+ await dispatch("delLeftVisitedRoute", route);
+ return {
+ visitedRoutes: [...state.visitedRoutes],
+ };
+ },
+ async delRightRoutes({ dispatch, state }, route) {
+ await dispatch("delRightVisitedRoute", route);
+ return {
+ visitedRoutes: [...state.visitedRoutes],
+ };
+ },
+ delOthersVisitedRoute({ commit, state }, route) {
+ commit("delOthersVisitedRoute", route);
+ return [...state.visitedRoutes];
+ },
+ delLeftVisitedRoute({ commit, state }, route) {
+ commit("delLeftVisitedRoute", route);
+ return [...state.visitedRoutes];
+ },
+ delRightVisitedRoute({ commit, state }, route) {
+ commit("delRightVisitedRoute", route);
+ return [...state.visitedRoutes];
+ },
+ async delAllRoutes({ dispatch, state }, route) {
+ await dispatch("delAllVisitedRoutes", route);
+ return {
+ visitedRoutes: [...state.visitedRoutes],
+ };
+ },
+ delAllVisitedRoutes({ commit, state }) {
+ commit("delAllVisitedRoutes");
+ return [...state.visitedRoutes];
+ },
+ updateVisitedRoute({ commit }, route) {
+ commit("updateVisitedRoute", route);
+ },
+};
+export default { state, getters, mutations, actions };
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
new file mode 100644
index 0000000..e1064c4
--- /dev/null
+++ b/src/store/modules/user.js
@@ -0,0 +1,99 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 登录、获取用户信息、退出登录、清除accessToken逻辑,不建议修改
+ */
+
+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/settings";
+
+const state = {
+ accessToken: getAccessToken(),
+ username: "",
+ avatar: "",
+ permissions: [],
+};
+const getters = {
+ accessToken: (state) => state.accessToken,
+ username: (state) => state.username,
+ avatar: (state) => state.avatar,
+ permissions: (state) => state.permissions,
+};
+const mutations = {
+ setAccessToken(state, accessToken) {
+ state.accessToken = accessToken;
+ setAccessToken(accessToken);
+ },
+ setUsername(state, username) {
+ state.username = username;
+ },
+ setAvatar(state, avatar) {
+ state.avatar = avatar;
+ },
+ setPermissions(state, permissions) {
+ state.permissions = permissions;
+ },
+};
+const actions = {
+ setPermissions({ commit }, permissions) {
+ commit("setPermissions", permissions);
+ },
+ async login({ commit }, userInfo) {
+ const { data } = await login(userInfo);
+ const accessToken = data[tokenName];
+ if (accessToken) {
+ commit("setAccessToken", accessToken);
+ const hour = new Date().getHours();
+ const thisTime =
+ hour < 8
+ ? "早上好"
+ : hour <= 11
+ ? "上午好"
+ : hour <= 13
+ ? "中午好"
+ : hour < 18
+ ? "下午好"
+ : "晚上好";
+ Vue.prototype.$baseNotify(`欢迎登录${title}`, `${thisTime}!`);
+ } else {
+ Vue.prototype.$baseMessage(
+ `登录接口异常,未正确返回${tokenName}...`,
+ "error"
+ );
+ }
+ },
+ async getUserInfo({ commit, state }) {
+ const { data } = await getUserInfo(state.accessToken);
+ if (!data) {
+ Vue.prototype.$baseMessage("验证失败,请重新登录...", "error");
+ return false;
+ }
+ let { permissions, username, avatar } = data;
+ if (permissions && username && Array.isArray(permissions)) {
+ commit("setPermissions", permissions);
+ commit("setUsername", username);
+ commit("setAvatar", avatar);
+ return permissions;
+ } else {
+ Vue.prototype.$baseMessage("用户信息接口异常", "error");
+ return false;
+ }
+ },
+ async logout({ dispatch }) {
+ await logout(state.accessToken);
+ await dispatch("resetAccessToken");
+ await resetRouter();
+ },
+ resetAccessToken({ commit }) {
+ commit("setPermissions", []);
+ commit("setAccessToken", "");
+ removeAccessToken();
+ },
+};
+export default { state, getters, mutations, actions };
diff --git a/src/styles/element-variables.scss b/src/styles/element-variables.scss
new file mode 100644
index 0000000..8da98a7
--- /dev/null
+++ b/src/styles/element-variables.scss
@@ -0,0 +1,1037 @@
+@charset "utf-8";
+
+/* Transition
+-------------------------- */
+$--all-transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+$--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);
+$--fade-linear-transition: opacity 200ms linear;
+$--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1),
+ opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);
+$--border-transition-base: border-color 0.2s
+ cubic-bezier(0.645, 0.045, 0.355, 1);
+$--color-transition-base: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+
+/* Color
+-------------------------- */
+/// color|1|Brand Color|0
+$--color-primary: $base-color-blue;
+/// color|1|Background Color|4
+$--color-white: #fff;
+/// color|1|Background Color|4
+$--color-black: #000;
+$--color-primary-light-1: mix($--color-white, $--color-primary, 10%);
+
+/* 53a8ff */
+$--color-primary-light-2: mix($--color-white, $--color-primary, 20%);
+
+/* 66b1ff */
+$--color-primary-light-3: mix($--color-white, $--color-primary, 30%);
+
+/* 79bbff */
+$--color-primary-light-4: mix($--color-white, $--color-primary, 40%);
+
+/* 8cc5ff */
+$--color-primary-light-5: mix($--color-white, $--color-primary, 50%);
+
+/* a0cfff */
+$--color-primary-light-6: mix($--color-white, $--color-primary, 60%);
+
+/* b3d8ff */
+$--color-primary-light-7: mix($--color-white, $--color-primary, 70%);
+
+/* c6e2ff */
+$--color-primary-light-8: mix($--color-white, $--color-primary, 80%);
+
+/* d9ecff */
+$--color-primary-light-9: mix($--color-white, $--color-primary, 90%);
+
+/* ecf5ff */
+/// color|1|Functional Color|1
+$--color-success: $base-color-green;
+/// color|1|Functional Color|1
+$--color-warning: $base-color-yellow;
+/// color|1|Functional Color|1
+$--color-danger: $base-color-red;
+/// color|1|Functional Color|1
+$--color-info: #909399;
+
+$--color-success-light: mix($--color-white, $--color-success, 80%);
+$--color-warning-light: mix($--color-white, $--color-warning, 80%);
+$--color-danger-light: mix($--color-white, $--color-danger, 80%);
+$--color-info-light: mix($--color-white, $--color-info, 80%);
+
+$--color-success-lighter: mix($--color-white, $--color-success, 90%);
+$--color-warning-lighter: mix($--color-white, $--color-warning, 90%);
+$--color-danger-lighter: mix($--color-white, $--color-danger, 90%);
+$--color-info-lighter: mix($--color-white, $--color-info, 90%);
+/// color|1|Font Color|2
+$--color-text-primary: #303133;
+/// color|1|Font Color|2
+$--color-text-regular: #606266;
+/// color|1|Font Color|2
+$--color-text-secondary: #909399;
+/// color|1|Font Color|2
+$--color-text-placeholder: #c0c4cc;
+/// color|1|Border Color|3
+$--border-color-base: #dcdfe6;
+/// color|1|Border Color|3
+$--border-color-light: #e4e7ed;
+/// color|1|Border Color|3
+$--border-color-lighter: #ebeef5;
+/// color|1|Border Color|3
+$--border-color-extra-light: #f2f6fc;
+
+// Background
+/// color|1|Background Color|4
+$--background-color-base: #f5f7fa;
+
+/* Link
+-------------------------- */
+$--link-color: $--color-primary-light-2;
+$--link-hover-color: $--color-primary;
+
+/* Border
+-------------------------- */
+$--border-width-base: 1px;
+$--border-style-base: solid;
+$--border-color-hover: $--color-text-placeholder;
+$--border-base: $--border-width-base $--border-style-base $--border-color-base;
+/// borderRadius|1|Radius|0
+$--border-radius-base: $base-border-radius;
+/// borderRadius|1|Radius|0
+$--border-radius-small: $base-border-radius;
+/// borderRadius|1|Radius|0
+$--border-radius-circle: 100%;
+/// borderRadius|1|Radius|0
+$--border-radius-zero: 0;
+
+// Box-shadow
+/// boxShadow|1|Shadow|1
+$--box-shadow-base: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+// boxShadow|1|Shadow|1
+$--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.12);
+/// boxShadow|1|Shadow|1
+$--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+/* Fill
+-------------------------- */
+$--fill-base: $--color-white;
+
+/* Typography
+-------------------------- */
+$--font-path: "~element-ui/lib/theme-chalk/fonts";
+$--font-display: "auto";
+/// fontSize|1|Font Size|0
+$--font-size-extra-large: 20px;
+/// fontSize|1|Font Size|0
+$--font-size-large: 18px;
+/// fontSize|1|Font Size|0
+$--font-size-medium: 16px;
+/// fontSize|1|Font Size|0
+$--font-size-base: 14px;
+/// fontSize|1|Font Size|0
+$--font-size-small: 13px;
+/// fontSize|1|Font Size|0
+$--font-size-extra-small: 12px;
+/// fontWeight|1|Font Weight|1
+$--font-weight-primary: 500;
+/// fontWeight|1|Font Weight|1
+$--font-weight-secondary: 100;
+/// fontLineHeight|1|Line Height|2
+$--font-line-height-primary: 24px;
+/// fontLineHeight|1|Line Height|2
+$--font-line-height-secondary: 16px;
+$--font-color-disabled-base: #bbb;
+
+/* Size
+-------------------------- */
+$--size-base: 14px;
+
+/* z-index
+-------------------------- */
+$--index-normal: 1;
+$--index-top: 1000;
+$--index-popper: 2000;
+
+/* Disable base
+-------------------------- */
+$--disabled-fill-base: $--background-color-base;
+$--disabled-color-base: $--color-text-placeholder;
+$--disabled-border-base: $--border-color-light;
+
+/* Icon
+-------------------------- */
+$--icon-color: #666;
+$--icon-color-base: $--color-info;
+
+/* Checkbox
+-------------------------- */
+/// fontSize||Font|1
+$--checkbox-font-size: 14px;
+/// fontWeight||Font|1
+$--checkbox-font-weight: $--font-weight-primary;
+/// color||Color|0
+$--checkbox-font-color: $--color-text-regular;
+$--checkbox-input-height: 14px;
+$--checkbox-input-width: 14px;
+/// borderRadius||Border|2
+$--checkbox-border-radius: $--border-radius-small;
+/// color||Color|0
+$--checkbox-background-color: $--color-white;
+$--checkbox-input-border: $--border-base;
+
+/// color||Color|0
+$--checkbox-disabled-border-color: $--border-color-base;
+$--checkbox-disabled-input-fill: #edf2fc;
+$--checkbox-disabled-icon-color: $--color-text-placeholder;
+
+$--checkbox-disabled-checked-input-fill: $--border-color-extra-light;
+$--checkbox-disabled-checked-input-border-color: $--border-color-base;
+$--checkbox-disabled-checked-icon-color: $--color-text-placeholder;
+
+/// color||Color|0
+$--checkbox-checked-font-color: $--color-primary;
+$--checkbox-checked-input-border-color: $--color-primary;
+/// color||Color|0
+$--checkbox-checked-background-color: $--color-primary;
+$--checkbox-checked-icon-color: $--fill-base;
+
+$--checkbox-input-border-color-hover: $--color-primary;
+/// height||Other|4
+$--checkbox-bordered-height: 40px;
+/// padding||Spacing|3
+$--checkbox-bordered-padding: 9px 20px 9px 10px;
+/// padding||Spacing|3
+$--checkbox-bordered-medium-padding: 7px 20px 7px 10px;
+/// padding||Spacing|3
+$--checkbox-bordered-small-padding: 5px 15px 5px 10px;
+/// padding||Spacing|3
+$--checkbox-bordered-mini-padding: 3px 15px 3px 10px;
+$--checkbox-bordered-medium-input-height: 14px;
+$--checkbox-bordered-medium-input-width: 14px;
+/// height||Other|4
+$--checkbox-bordered-medium-height: 36px;
+$--checkbox-bordered-small-input-height: 12px;
+$--checkbox-bordered-small-input-width: 12px;
+/// height||Other|4
+$--checkbox-bordered-small-height: 32px;
+$--checkbox-bordered-mini-input-height: 12px;
+$--checkbox-bordered-mini-input-width: 12px;
+/// height||Other|4
+$--checkbox-bordered-mini-height: 28px;
+
+/// color||Color|0
+$--checkbox-button-checked-background-color: $--color-primary;
+/// color||Color|0
+$--checkbox-button-checked-font-color: $--color-white;
+/// color||Color|0
+$--checkbox-button-checked-border-color: $--color-primary;
+
+/* Radio
+-------------------------- */
+/// fontSize||Font|1
+$--radio-font-size: $--font-size-base;
+/// fontWeight||Font|1
+$--radio-font-weight: $--font-weight-primary;
+/// color||Color|0
+$--radio-font-color: $--color-text-regular;
+$--radio-input-height: 14px;
+$--radio-input-width: 14px;
+/// borderRadius||Border|2
+$--radio-input-border-radius: $--border-radius-circle;
+/// color||Color|0
+$--radio-input-background-color: $--color-white;
+$--radio-input-border: $--border-base;
+/// color||Color|0
+$--radio-input-border-color: $--border-color-base;
+/// color||Color|0
+$--radio-icon-color: $--color-white;
+
+$--radio-disabled-input-border-color: $--disabled-border-base;
+$--radio-disabled-input-fill: $--disabled-fill-base;
+$--radio-disabled-icon-color: $--disabled-fill-base;
+
+$--radio-disabled-checked-input-border-color: $--disabled-border-base;
+$--radio-disabled-checked-input-fill: $--disabled-fill-base;
+$--radio-disabled-checked-icon-color: $--color-text-placeholder;
+
+/// color||Color|0
+$--radio-checked-font-color: $--color-primary;
+/// color||Color|0
+$--radio-checked-input-border-color: $--color-primary;
+/// color||Color|0
+$--radio-checked-input-background-color: $--color-white;
+/// color||Color|0
+$--radio-checked-icon-color: $--color-primary;
+
+$--radio-input-border-color-hover: $--color-primary;
+
+$--radio-bordered-height: 40px;
+$--radio-bordered-padding: 12px 20px 0 10px;
+$--radio-bordered-medium-padding: 10px 20px 0 10px;
+$--radio-bordered-small-padding: 8px 15px 0 10px;
+$--radio-bordered-mini-padding: 6px 15px 0 10px;
+$--radio-bordered-medium-input-height: 14px;
+$--radio-bordered-medium-input-width: 14px;
+$--radio-bordered-medium-height: 36px;
+$--radio-bordered-small-input-height: 12px;
+$--radio-bordered-small-input-width: 12px;
+$--radio-bordered-small-height: 32px;
+$--radio-bordered-mini-input-height: 12px;
+$--radio-bordered-mini-input-width: 12px;
+$--radio-bordered-mini-height: 28px;
+
+/// fontSize||Font|1
+$--radio-button-font-size: $--font-size-base;
+/// color||Color|0
+$--radio-button-checked-background-color: $--color-primary;
+/// color||Color|0
+$--radio-button-checked-font-color: $--color-white;
+/// color||Color|0
+$--radio-button-checked-border-color: $--color-primary;
+$--radio-button-disabled-checked-fill: $--border-color-extra-light;
+
+/* Select
+-------------------------- */
+$--select-border-color-hover: $--border-color-hover;
+$--select-disabled-border: $--disabled-border-base;
+/// fontSize||Font|1
+$--select-font-size: $--font-size-base;
+$--select-close-hover-color: $--color-text-secondary;
+
+$--select-input-color: $--color-text-placeholder;
+$--select-multiple-input-color: #666;
+/// color||Color|0
+$--select-input-focus-border-color: $--color-primary;
+/// fontSize||Font|1
+$--select-input-font-size: 14px;
+
+$--select-option-color: $--color-text-regular;
+$--select-option-disabled-color: $--color-text-placeholder;
+$--select-option-disabled-background: $--color-white;
+/// height||Other|4
+$--select-option-height: 34px;
+$--select-option-hover-background: $--background-color-base;
+/// color||Color|0
+$--select-option-selected-font-color: $--color-primary;
+$--select-option-selected-hover: $--background-color-base;
+
+$--select-group-color: $--color-info;
+$--select-group-height: 30px;
+$--select-group-font-size: 12px;
+
+$--select-dropdown-background: $--color-white;
+$--select-dropdown-shadow: $--box-shadow-light;
+$--select-dropdown-empty-color: #999;
+/// height||Other|4
+$--select-dropdown-max-height: 274px;
+$--select-dropdown-padding: 6px 0;
+$--select-dropdown-empty-padding: 10px 0;
+$--select-dropdown-border: solid 1px $--border-color-light;
+
+/* Alert
+-------------------------- */
+$--alert-padding: 8px 16px;
+/// borderRadius||Border|2
+$--alert-border-radius: $--border-radius-base;
+/// fontSize||Font|1
+$--alert-title-font-size: 13px;
+/// fontSize||Font|1
+$--alert-description-font-size: 12px;
+/// fontSize||Font|1
+$--alert-close-font-size: 12px;
+/// fontSize||Font|1
+$--alert-close-customed-font-size: 13px;
+
+$--alert-success-color: $--color-success-lighter;
+$--alert-info-color: $--color-info-lighter;
+$--alert-warning-color: $--color-warning-lighter;
+$--alert-danger-color: $--color-danger-lighter;
+
+/// height||Other|4
+$--alert-icon-size: 16px;
+/// height||Other|4
+$--alert-icon-large-size: 28px;
+
+/* MessageBox
+-------------------------- */
+/// color||Color|0
+$--messagebox-title-color: $--color-text-primary;
+$--msgbox-width: 420px;
+$--msgbox-border-radius: $--border-radius-base;
+/// fontSize||Font|1
+$--messagebox-font-size: $--font-size-large;
+/// fontSize||Font|1
+$--messagebox-content-font-size: $--font-size-base;
+/// color||Color|0
+$--messagebox-content-color: $--color-text-regular;
+/// fontSize||Font|1
+$--messagebox-error-font-size: 12px;
+$--msgbox-padding-primary: 15px;
+/// color||Color|0
+$--messagebox-success-color: $--color-success;
+/// color||Color|0
+$--messagebox-info-color: $--color-info;
+/// color||Color|0
+$--messagebox-warning-color: $--color-warning;
+/// color||Color|0
+$--messagebox-danger-color: $--color-danger;
+
+/* Message
+-------------------------- */
+$--message-shadow: $--box-shadow-base;
+$--message-min-width: 380px;
+$--message-background-color: #edf2fc;
+$--message-padding: 15px 15px 15px 20px;
+/// color||Color|0
+$--message-close-icon-color: $--color-text-placeholder;
+/// height||Other|4
+$--message-close-size: 16px;
+/// color||Color|0
+$--message-close-hover-color: $--color-text-secondary;
+
+/// color||Color|0
+$--message-success-font-color: $--color-success;
+/// color||Color|0
+$--message-info-font-color: $--color-info;
+/// color||Color|0
+$--message-warning-font-color: $--color-warning;
+/// color||Color|0
+$--message-danger-font-color: $--color-danger;
+
+/* Notification
+-------------------------- */
+$--notification-width: 330px;
+/// padding||Spacing|3
+$--notification-padding: 14px 26px 14px 13px;
+$--notification-radius: 8px;
+$--notification-shadow: $--box-shadow-light;
+/// color||Color|0
+$--notification-border-color: $--border-color-lighter;
+$--notification-icon-size: 24px;
+$--notification-close-font-size: $--message-close-size;
+$--notification-group-margin-left: 13px;
+$--notification-group-margin-right: 8px;
+/// fontSize||Font|1
+$--notification-content-font-size: $--font-size-base;
+/// color||Color|0
+$--notification-content-color: $--color-text-regular;
+/// fontSize||Font|1
+$--notification-title-font-size: 16px;
+/// color||Color|0
+$--notification-title-color: $--color-text-primary;
+
+/// color||Color|0
+$--notification-close-color: $--color-text-secondary;
+/// color||Color|0
+$--notification-close-hover-color: $--color-text-regular;
+
+/// color||Color|0
+$--notification-success-icon-color: $--color-success;
+/// color||Color|0
+$--notification-info-icon-color: $--color-info;
+/// color||Color|0
+$--notification-warning-icon-color: $--color-warning;
+/// color||Color|0
+$--notification-danger-icon-color: $--color-danger;
+
+/* Input
+-------------------------- */
+$--input-font-size: $--font-size-base;
+/// color||Color|0
+$--input-font-color: $--color-text-regular;
+/// height||Other|4
+$--input-width: 140px;
+/// height||Other|4
+$--input-height: 40px;
+$--input-border: $--border-base;
+$--input-border-color: $--border-color-base;
+/// borderRadius||Border|2
+$--input-border-radius: $--border-radius-base;
+$--input-border-color-hover: $--border-color-hover;
+/// color||Color|0
+$--input-background-color: $--color-white;
+$--input-fill-disabled: $--disabled-fill-base;
+$--input-color-disabled: $--font-color-disabled-base;
+/// color||Color|0
+$--input-icon-color: $--color-text-placeholder;
+/// color||Color|0
+$--input-placeholder-color: $--color-text-placeholder;
+$--input-max-width: 314px;
+
+$--input-hover-border: $--border-color-hover;
+$--input-clear-hover-color: $--color-text-secondary;
+
+$--input-focus-border: $--color-primary;
+$--input-focus-fill: $--color-white;
+
+$--input-disabled-fill: $--disabled-fill-base;
+$--input-disabled-border: $--disabled-border-base;
+$--input-disabled-color: $--disabled-color-base;
+$--input-disabled-placeholder-color: $--color-text-placeholder;
+
+/// fontSize||Font|1
+$--input-medium-font-size: 14px;
+/// height||Other|4
+$--input-medium-height: 36px;
+/// fontSize||Font|1
+$--input-small-font-size: 13px;
+/// height||Other|4
+$--input-small-height: 32px;
+/// fontSize||Font|1
+$--input-mini-font-size: 12px;
+/// height||Other|4
+$--input-mini-height: 28px;
+
+/* Cascader
+-------------------------- */
+/// color||Color|0
+$--cascader-menu-font-color: $--color-text-regular;
+/// color||Color|0
+$--cascader-menu-selected-font-color: $--color-primary;
+$--cascader-menu-fill: $--fill-base;
+$--cascader-menu-font-size: $--font-size-base;
+$--cascader-menu-radius: $--border-radius-base;
+$--cascader-menu-border: solid 1px $--border-color-light;
+$--cascader-menu-shadow: $--box-shadow-light;
+$--cascader-node-background-hover: $--background-color-base;
+$--cascader-node-color-disabled: $--color-text-placeholder;
+$--cascader-color-empty: $--color-text-placeholder;
+$--cascader-tag-background: #f0f2f5;
+
+/* Group
+-------------------------- */
+$--group-option-flex: 0 0 (1/5) * 100%;
+$--group-option-offset-bottom: 12px;
+$--group-option-fill-hover: rgba($--color-black, 0.06);
+$--group-title-color: $--color-black;
+$--group-title-font-size: $--font-size-base;
+$--group-title-width: 66px;
+
+/* Tab
+-------------------------- */
+$--tab-font-size: $--font-size-base;
+$--tab-border-line: 1px solid #e4e4e4;
+$--tab-header-color-active: $--color-text-secondary;
+$--tab-header-color-hover: $--color-text-regular;
+$--tab-header-color: $--color-text-regular;
+$--tab-header-fill-active: rgba($--color-black, 0.06);
+$--tab-header-fill-hover: rgba($--color-black, 0.06);
+$--tab-vertical-header-width: 90px;
+$--tab-vertical-header-count-color: $--color-white;
+$--tab-vertical-header-count-fill: $--color-text-secondary;
+
+/* Button
+-------------------------- */
+/// fontSize||Font|1
+$--button-font-size: $--font-size-base;
+/// fontWeight||Font|1
+$--button-font-weight: $--font-weight-primary;
+/// borderRadius||Border|2
+$--button-border-radius: $--border-radius-base;
+/// padding||Spacing|3
+$--button-padding-vertical: 12px;
+/// padding||Spacing|3
+$--button-padding-horizontal: 20px;
+
+/// fontSize||Font|1
+$--button-medium-font-size: $--font-size-base;
+/// borderRadius||Border|2
+$--button-medium-border-radius: $--border-radius-base;
+/// padding||Spacing|3
+$--button-medium-padding-vertical: 10px;
+/// padding||Spacing|3
+$--button-medium-padding-horizontal: 20px;
+
+/// fontSize||Font|1
+$--button-small-font-size: 12px;
+$--button-small-border-radius: $--border-radius-base;
+/// padding||Spacing|3
+$--button-small-padding-vertical: 9px;
+/// padding||Spacing|3
+$--button-small-padding-horizontal: 15px;
+/// fontSize||Font|1
+$--button-mini-font-size: 12px;
+$--button-mini-border-radius: $--border-radius-base;
+/// padding||Spacing|3
+$--button-mini-padding-vertical: 7px;
+/// padding||Spacing|3
+$--button-mini-padding-horizontal: 15px;
+
+/// color||Color|0
+$--button-default-font-color: $--color-text-regular;
+/// color||Color|0
+$--button-default-background-color: $--color-white;
+/// color||Color|0
+$--button-default-border-color: $--border-color-base;
+
+/// color||Color|0
+$--button-disabled-font-color: $--color-text-placeholder;
+/// color||Color|0
+$--button-disabled-background-color: $--color-white;
+/// color||Color|0
+$--button-disabled-border-color: $--border-color-lighter;
+
+/// color||Color|0
+$--button-primary-border-color: $--color-primary;
+/// color||Color|0
+$--button-primary-font-color: $--color-white;
+/// color||Color|0
+$--button-primary-background-color: $--color-primary;
+/// color||Color|0
+$--button-success-border-color: $--color-success;
+/// color||Color|0
+$--button-success-font-color: $--color-white;
+/// color||Color|0
+$--button-success-background-color: $--color-success;
+/// color||Color|0
+$--button-warning-border-color: $--color-warning;
+/// color||Color|0
+$--button-warning-font-color: $--color-white;
+/// color||Color|0
+$--button-warning-background-color: $--color-warning;
+/// color||Color|0
+$--button-danger-border-color: $--color-danger;
+/// color||Color|0
+$--button-danger-font-color: $--color-white;
+/// color||Color|0
+$--button-danger-background-color: $--color-danger;
+/// color||Color|0
+$--button-info-border-color: $--color-info;
+/// color||Color|0
+$--button-info-font-color: $--color-white;
+/// color||Color|0
+$--button-info-background-color: $--color-info;
+
+$--button-hover-tint-percent: 20%;
+$--button-active-shade-percent: 10%;
+
+/* cascader
+-------------------------- */
+$--cascader-height: 200px;
+
+/* Switch
+-------------------------- */
+/// color||Color|0
+$--switch-on-color: $--color-primary;
+/// color||Color|0
+$--switch-off-color: $--border-color-base;
+/// fontSize||Font|1
+$--switch-font-size: $--font-size-base;
+$--switch-core-border-radius: 10px;
+// height||Other|4 TODO: width 代码写死的40px 所以下面这三个属性都没意义
+$--switch-width: 40px;
+// height||Other|4
+$--switch-height: 20px;
+// height||Other|4
+$--switch-button-size: 16px;
+
+/* Dialog
+-------------------------- */
+$--dialog-background-color: $--color-white;
+$--dialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+/// fontSize||Font|1
+$--dialog-title-font-size: $--font-size-large;
+/// fontSize||Font|1
+$--dialog-content-font-size: 14px;
+/// fontLineHeight||LineHeight|2
+$--dialog-font-line-height: $--font-line-height-primary;
+/// padding||Spacing|3
+$--dialog-padding-primary: 20px;
+
+/* Table
+-------------------------- */
+/// color||Color|0
+$--table-border-color: $--border-color-lighter;
+$--table-border: 1px solid $--table-border-color;
+/// color||Color|0
+$--table-font-color: $--color-text-regular;
+/// color||Color|0
+$--table-header-font-color: $--color-text-secondary;
+/// color||Color|0
+$--table-row-hover-background-color: $--background-color-base;
+$--table-current-row-background-color: $--color-primary-light-9;
+/// color||Color|0
+$--table-header-background-color: $--color-white;
+$--table-fixed-box-shadow: 0 0 10px rgba(0, 0, 0, 0.12);
+
+/* Pagination
+-------------------------- */
+/// fontSize||Font|1
+$--pagination-font-size: 13px;
+/// color||Color|0
+$--pagination-background-color: $--color-white;
+/// color||Color|0
+$--pagination-font-color: $--color-text-primary;
+$--pagination-border-radius: $--border-radius-base;
+/// color||Color|0
+$--pagination-button-color: $--color-text-primary;
+/// height||Other|4
+$--pagination-button-width: 35.5px;
+/// height||Other|4
+$--pagination-button-height: 28px;
+/// color||Color|0
+$--pagination-button-disabled-color: $--color-text-placeholder;
+/// color||Color|0
+$--pagination-button-disabled-background-color: $--color-white;
+/// color||Color|0
+$--pagination-hover-color: $--color-primary;
+
+/* Popup
+-------------------------- */
+/// color||Color|0
+$--popup-modal-background-color: $--color-black;
+/// opacity||Other|1
+$--popup-modal-opacity: 0.5;
+
+/* Popover
+-------------------------- */
+/// color||Color|0
+$--popover-background-color: $--color-white;
+/// fontSize||Font|1
+$--popover-font-size: $--font-size-base;
+/// color||Color|0
+$--popover-border-color: $--border-color-lighter;
+$--popover-arrow-size: 6px;
+/// padding||Spacing|3
+$--popover-padding: 12px;
+$--popover-padding-large: 18px 20px;
+/// fontSize||Font|1
+$--popover-title-font-size: 16px;
+/// color||Color|0
+$--popover-title-font-color: $--color-text-primary;
+
+/* Tooltip
+-------------------------- */
+/// color|1|Color|0
+$--tooltip-fill: $--color-text-primary;
+/// color|1|Color|0
+$--tooltip-color: $--color-white;
+/// fontSize||Font|1
+$--tooltip-font-size: 12px;
+/// color||Color|0
+$--tooltip-border-color: $--color-text-primary;
+$--tooltip-arrow-size: 6px;
+/// padding||Spacing|3
+$--tooltip-padding: 10px;
+
+/* Tag
+-------------------------- */
+/// color||Color|0
+$--tag-info-color: $--color-info;
+/// color||Color|0
+$--tag-primary-color: $--color-primary;
+/// color||Color|0
+$--tag-success-color: $--color-success;
+/// color||Color|0
+$--tag-warning-color: $--color-warning;
+/// color||Color|0
+$--tag-danger-color: $--color-danger;
+/// fontSize||Font|1
+$--tag-font-size: 12px;
+$--tag-border-radius: $--border-radius-base;
+$--tag-padding: 0 10px;
+
+/* Tree
+-------------------------- */
+/// color||Color|0
+$--tree-node-hover-background-color: $--background-color-base;
+/// color||Color|0
+$--tree-font-color: $--color-text-regular;
+/// color||Color|0
+$--tree-expand-icon-color: $--color-text-placeholder;
+
+/* Dropdown
+-------------------------- */
+$--dropdown-menu-box-shadow: $--box-shadow-light;
+$--dropdown-menuItem-hover-fill: $--color-primary-light-9;
+$--dropdown-menuItem-hover-color: $--link-color;
+
+/* Badge
+-------------------------- */
+/// color||Color|0
+$--badge-background-color: $--color-danger;
+$--badge-radius: 10px;
+/// fontSize||Font|1
+$--badge-font-size: 12px;
+/// padding||Spacing|3
+$--badge-padding: 6px;
+/// height||Other|4
+$--badge-size: 18px;
+
+/* Card
+-------------------------- */
+/// color||Color|0
+$--card-border-color: $--border-color-lighter;
+$--card-border-radius: $--border-radius-base;
+/// padding||Spacing|3
+$--card-padding: 20px;
+
+/* Slider
+-------------------------- */
+/// color||Color|0
+$--slider-main-background-color: $--color-primary;
+/// color||Color|0
+$--slider-runway-background-color: $--border-color-light;
+$--slider-button-hover-color: mix($--color-primary, black, 97%);
+$--slider-stop-background-color: $--color-white;
+$--slider-disable-color: $--color-text-placeholder;
+$--slider-margin: 16px 0;
+$--slider-border-radius: $--border-radius-base;
+/// height|1|Other|4
+$--slider-height: 6px;
+/// height||Other|4
+$--slider-button-size: 16px;
+$--slider-button-wrapper-size: 36px;
+$--slider-button-wrapper-offset: -15px;
+
+/* Steps
+-------------------------- */
+$--steps-border-color: $--disabled-border-base;
+$--steps-border-radius: $--border-radius-base;
+$--steps-padding: 20px;
+
+/* Menu
+-------------------------- */
+/// fontSize||Font|1
+$--menu-item-font-size: $--font-size-base;
+/// color||Color|0
+$--menu-item-font-color: $--color-text-primary;
+/// color||Color|0
+$--menu-background-color: $--color-white;
+$--menu-item-hover-fill: $--color-primary-light-9;
+
+/* Rate
+-------------------------- */
+$--rate-height: 20px;
+/// fontSize||Font|1
+$--rate-font-size: $--font-size-base;
+/// height||Other|3
+$--rate-icon-size: 18px;
+/// margin||Spacing|2
+$--rate-icon-margin: 6px;
+$--rate-icon-color: $--color-text-placeholder;
+
+/* DatePicker
+-------------------------- */
+$--datepicker-font-color: $--color-text-regular;
+/// color|1|Color|0
+$--datepicker-off-font-color: $--color-text-placeholder;
+/// color||Color|0
+$--datepicker-header-font-color: $--color-text-regular;
+$--datepicker-icon-color: $--color-text-primary;
+$--datepicker-border-color: $--disabled-border-base;
+$--datepicker-inner-border-color: #e4e4e4;
+/// color||Color|0
+$--datepicker-inrange-background-color: $--border-color-extra-light;
+/// color||Color|0
+$--datepicker-inrange-hover-background-color: $--border-color-extra-light;
+/// color||Color|0
+$--datepicker-active-color: $--color-primary;
+/// color||Color|0
+$--datepicker-hover-font-color: $--color-primary;
+$--datepicker-cell-hover-color: #fff;
+
+/* Loading
+-------------------------- */
+/// height||Other|4
+$--loading-spinner-size: 42px;
+/// height||Other|4
+$--loading-fullscreen-spinner-size: 50px;
+
+/* Scrollbar
+-------------------------- */
+$--scrollbar-background-color: rgba($--color-text-secondary, 0.3);
+$--scrollbar-hover-background-color: rgba($--color-text-secondary, 0.5);
+
+/* Carousel
+-------------------------- */
+/// fontSize||Font|1
+$--carousel-arrow-font-size: 12px;
+$--carousel-arrow-size: 36px;
+$--carousel-arrow-background: rgba(31, 45, 61, 0.11);
+$--carousel-arrow-hover-background: rgba(31, 45, 61, 0.23);
+/// width||Other|4
+$--carousel-indicator-width: 30px;
+/// height||Other|4
+$--carousel-indicator-height: 2px;
+$--carousel-indicator-padding-horizontal: 4px;
+$--carousel-indicator-padding-vertical: 12px;
+$--carousel-indicator-out-color: $--border-color-hover;
+
+/* Collapse
+-------------------------- */
+/// color||Color|0
+$--collapse-border-color: $--border-color-lighter;
+/// height||Other|4
+$--collapse-header-height: 48px;
+/// color||Color|0
+$--collapse-header-background-color: $--color-white;
+/// color||Color|0
+$--collapse-header-font-color: $--color-text-primary;
+/// fontSize||Font|1
+$--collapse-header-font-size: 13px;
+/// color||Color|0
+$--collapse-content-background-color: $--color-white;
+/// fontSize||Font|1
+$--collapse-content-font-size: 13px;
+/// color||Color|0
+$--collapse-content-font-color: $--color-text-primary;
+
+/* Transfer
+-------------------------- */
+$--transfer-border-color: $--border-color-lighter;
+$--transfer-border-radius: $--border-radius-base;
+/// height||Other|4
+$--transfer-panel-width: 200px;
+/// height||Other|4
+$--transfer-panel-header-height: 40px;
+/// color||Color|0
+$--transfer-panel-header-background-color: $--background-color-base;
+/// height||Other|4
+$--transfer-panel-footer-height: 40px;
+/// height||Other|4
+$--transfer-panel-body-height: 246px;
+/// height||Other|4
+$--transfer-item-height: 30px;
+/// height||Other|4
+$--transfer-filter-height: 32px;
+
+/* Header
+ -------------------------- */
+$--header-padding: 0 20px;
+
+/* Footer
+-------------------------- */
+$--footer-padding: 0 20px;
+
+/* Main
+-------------------------- */
+$--main-padding: 20px;
+
+/* Timeline
+-------------------------- */
+$--timeline-node-size-normal: 12px;
+$--timeline-node-size-large: 14px;
+$--timeline-node-color: $--border-color-light;
+
+/* Backtop
+-------------------------- */
+/// color||Color|0
+$--backtop-background-color: $--color-white;
+/// color||Color|0
+$--backtop-font-color: $--color-primary;
+/// color||Color|0
+$--backtop-hover-background-color: $--border-color-extra-light;
+
+/* Link
+-------------------------- */
+/// fontSize||Font|1
+$--link-font-size: $--font-size-base;
+/// fontWeight||Font|1
+$--link-font-weight: $--font-weight-primary;
+/// color||Color|0
+$--link-default-font-color: $--color-text-regular;
+/// color||Color|0
+$--link-default-active-color: $--color-primary;
+/// color||Color|0
+$--link-disabled-font-color: $--color-text-placeholder;
+/// color||Color|0
+$--link-primary-font-color: $--color-primary;
+/// color||Color|0
+$--link-success-font-color: $--color-success;
+/// color||Color|0
+$--link-warning-font-color: $--color-warning;
+/// color||Color|0
+$--link-danger-font-color: $--color-danger;
+/// color||Color|0
+$--link-info-font-color: $--color-info;
+
+/* Calendar
+-------------------------- */
+/// border||Other|4
+$--calendar-border: $--table-border;
+/// color||Other|4
+$--calendar-selected-background-color: #f2f8fe;
+$--calendar-cell-width: 85px;
+
+/* Form
+-------------------------- */
+/// fontSize||Font|1
+$--form-label-font-size: $--font-size-base;
+
+/* Avatar
+-------------------------- */
+/// color||Color|0
+$--avatar-font-color: #fff;
+/// color||Color|0
+$--avatar-background-color: #c0c4cc;
+/// fontSize||Font Size|1
+$--avatar-text-font-size: 14px;
+/// fontSize||Font Size|1
+$--avatar-icon-font-size: 18px;
+/// borderRadius||Border|2
+$--avatar-border-radius: $--border-radius-base;
+/// size|1|Avatar Size|3
+$--avatar-large-size: 40px;
+/// size|1|Avatar Size|3
+$--avatar-medium-size: 36px;
+/// size|1|Avatar Size|3
+$--avatar-small-size: 28px;
+
+/* Break-point
+-------------------------- */
+$--sm: 768px;
+$--md: 992px;
+$--lg: 1200px;
+$--xl: 1920px;
+
+$--breakpoints: (
+ "xs": (
+ max-width: $--sm - 1,
+ ),
+ "sm": (
+ min-width: $--sm,
+ ),
+ "md": (
+ min-width: $--md,
+ ),
+ "lg": (
+ min-width: $--lg,
+ ),
+ "xl": (
+ min-width: $--xl,
+ ),
+);
+
+$--breakpoints-spec: (
+ "xs-only": (
+ max-width: $--sm - 1,
+ ),
+ "sm-and-up": (
+ min-width: $--sm,
+ ),
+ "sm-only": "(min-width: #{$--sm}) and (max-width: #{$--md - 1})",
+ "sm-and-down": (
+ max-width: $--md - 1,
+ ),
+ "md-and-up": (
+ min-width: $--md,
+ ),
+ "md-only": "(min-width: #{$--md}) and (max-width: #{$--lg - 1})",
+ "md-and-down": (
+ max-width: $--lg - 1,
+ ),
+ "lg-and-up": (
+ min-width: $--lg,
+ ),
+ "lg-only": "(min-width: #{$--lg}) and (max-width: #{$--xl - 1})",
+ "lg-and-down": (
+ max-width: $--xl - 1,
+ ),
+ "xl-only": (
+ min-width: $--xl,
+ ),
+);
+
+@import "~element-ui/packages/theme-chalk/src/index";
diff --git a/src/styles/loading.scss b/src/styles/loading.scss
new file mode 100644
index 0000000..511dc25
--- /dev/null
+++ b/src/styles/loading.scss
@@ -0,0 +1,346 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局加载动画
+ */
+
+@charset "utf-8";
+
+@import "./spinner/dots.css";
+@import "./spinner/gauge.css";
+@import "./spinner/inner-circles.css";
+@import "./spinner/plus.css";
+
+$base-loading: ".vab-loading-type";
+
+/* 自定义loading开始 */
+#{$base-loading}1 {
+ display: flex;
+ width: 36px;
+ height: 36px;
+ margin: 0 auto 15px;
+ border: 3px solid transparent;
+ border-top-color: $base-color-blue;
+ border-bottom-color: $base-color-blue;
+ border-radius: 50%;
+ animation: vabLoading1-0 0.8s linear infinite;
+}
+
+#{$base-loading}1::before {
+ display: block;
+ width: 8px;
+ height: 8px;
+ margin: auto;
+ content: "";
+ border: 3px solid $base-color-blue;
+ border-radius: 50%;
+ animation: vabLoading1 0.5s alternate ease-in infinite;
+}
+
+@keyframes vabLoading1-0 {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes vabLoading1 {
+ from {
+ transform: scale(0.5);
+ }
+
+ to {
+ transform: scale(1.2);
+ }
+}
+
+#{$base-loading}2 {
+ width: 20px;
+ height: 20px;
+ margin-top: -40px;
+ margin-left: -10px;
+ animation: vabLoading2 1s linear reverse infinite;
+}
+
+#{$base-loading}2::before {
+ display: block;
+ width: 36px;
+ height: 36px;
+ margin-top: -17px;
+ margin-left: -18px;
+ content: "";
+ animation: vabLoading2 0.4s linear infinite;
+}
+
+#{$base-loading}2::after {
+ display: block;
+ width: 8px;
+ height: 8px;
+ margin-top: -3px;
+ margin-left: -4px;
+ content: "";
+ animation: vabLoading2 0.4s linear infinite;
+}
+
+#{$base-loading}2::before,
+#{$base-loading}2,
+#{$base-loading}2::after {
+ position: absolute;
+ top: 40%;
+ left: 50%;
+ border: 3px solid transparent;
+ border-top-color: $base-color-blue;
+ border-right-color: $base-color-blue;
+ border-radius: 50%;
+}
+
+@keyframes vabLoading2 {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+#{$base-loading}3 {
+ display: inline-block;
+ width: 2.5em;
+ height: 3em;
+ margin-bottom: 15px;
+ border: 3px solid transparent;
+ border-top-color: $base-color-blue;
+ border-bottom-color: $base-color-blue;
+ border-radius: 50%;
+ animation: vabLoading3 2s ease infinite;
+}
+
+@keyframes vabLoading3 {
+ 50% {
+ border-width: 8px;
+ transform: rotate(360deg) scale(0.4, 0.33);
+ }
+
+ 100% {
+ border-width: 3px;
+ transform: rotate(720deg) scale(1, 1);
+ }
+}
+
+#{$base-loading}4 {
+ display: inline-block;
+ width: 30px;
+ height: 30px;
+ margin: 0 auto 10px;
+ border: 8px solid transparent;
+ border-bottom-color: $base-color-blue;
+ border-left-color: $base-color-blue;
+ border-radius: 50%;
+ animation: vabLoading4 1s linear infinite normal;
+}
+
+#{$base-loading}4::after {
+ display: block;
+ width: 15px;
+ height: 15px;
+ margin: 0;
+ content: " ";
+ border: 6px solid $base-color-blue;
+ border-bottom-color: transparent;
+ border-left-color: transparent;
+ border-radius: 50%;
+}
+
+@keyframes vabLoading4 {
+ 0% {
+ opacity: 0.2;
+ transform: rotate(0deg);
+ }
+
+ 50% {
+ opacity: 1;
+ transform: rotate(180deg);
+ }
+
+ 100% {
+ opacity: 0.2;
+ transform: rotate(360deg);
+ }
+}
+
+#{$base-loading}5 {
+ display: block;
+ width: 0;
+ height: 0;
+ margin: 0 auto 15px;
+ border: solid 1.5em $base-color-blue;
+ border-right: solid 1.5em transparent;
+ border-left: solid 1.5em transparent;
+ border-radius: 100%;
+ animation: vabLoading5 1s linear infinite;
+}
+
+@keyframes vabLoading5 {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 50% {
+ transform: rotate(60deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+#{$base-loading}6 {
+ display: block;
+ width: 0;
+ height: 0;
+ margin: 0 auto 25px auto;
+ perspective: 200px;
+}
+
+#{$base-loading}6::before,
+#{$base-loading}6::after {
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ content: "";
+ background: rgba(0, 0, 0, 0);
+ animation: vabLoading6 0.5s infinite alternate;
+}
+
+#{$base-loading}6::before {
+ left: 0;
+}
+
+#{$base-loading}6::after {
+ right: 0;
+ animation-delay: 0.15s;
+}
+
+@keyframes vabLoading6 {
+ 0% {
+ box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+ transform: scale(1) translateY(0) rotateX(0deg);
+ }
+
+ 100% {
+ background: $base-color-blue;
+ box-shadow: 0 25px 40px rgba($base-color-blue, 0.5);
+ transform: scale(1.2) translateY(-25px) rotateX(45deg);
+ }
+}
+
+#{$base-loading}7 {
+ display: block;
+ width: 25px;
+ height: 25px;
+ margin: 0 auto 15px auto;
+ border: 2px solid $base-color-blue;
+ border-top-color: rgba($base-color-blue, 0.2);
+ border-right-color: rgba($base-color-blue, 0.2);
+ border-bottom-color: rgba($base-color-blue, 0.2);
+ border-radius: 100%;
+ animation: vabLoading7 infinite 0.75s linear;
+}
+
+@keyframes vabLoading7 {
+ 0% {
+ transform: rotate(0);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+#{$base-loading}8 {
+ position: relative;
+ box-sizing: border-box;
+ display: block;
+ width: 20px;
+ height: 20px;
+ margin: 0 auto 15px auto;
+ background-color: $base-color-blue;
+ border-radius: 50%;
+ box-shadow: 30px 0 0 0 $base-color-blue;
+ transform: translateX(-15px);
+}
+
+#{$base-loading}8::after {
+ position: absolute;
+ top: 8px;
+ left: 9px;
+ width: 10px;
+ height: 10px;
+ content: "";
+ background-color: $base-color-white;
+ border-radius: 50%;
+ box-shadow: 30px 0 0 0 $base-color-white;
+ animation: vabLoading8 2s ease-in-out infinite alternate;
+}
+
+@keyframes vabLoading8 {
+ 0% {
+ left: 9px;
+ }
+
+ 100% {
+ left: 1px;
+ }
+}
+
+#{$base-loading}9 {
+ position: relative;
+ box-sizing: border-box;
+ display: block;
+ width: 20px;
+ height: 20px;
+ margin: 0 auto 15px auto;
+ border: 1px $base-color-blue solid;
+ animation: vabLoading9 5s linear infinite;
+}
+
+#{$base-loading}9::after {
+ position: absolute;
+ top: -8px;
+ left: 0;
+ width: 4px;
+ height: 4px;
+ content: "";
+ background-color: $base-color-blue;
+ animation: vabLoading9_check 1s ease-in-out infinite;
+}
+
+@keyframes vabLoading9_check {
+ 25% {
+ top: -8px;
+ left: 22px;
+ }
+
+ 50% {
+ top: 22px;
+ left: 22px;
+ }
+
+ 75% {
+ top: 22px;
+ left: -9px;
+ }
+
+ 100% {
+ top: -7px;
+ left: -9px;
+ }
+}
+
+@keyframes vabLoading9 {
+ 0% {
+ box-shadow: inset 0 0 0 0 rgba($base-color-blue, 0.5);
+ opacity: 0.5;
+ }
+
+ 100% {
+ box-shadow: inset 0 -20px 0 0 $base-color-blue;
+ }
+}
+
+/* 自定义loading结束 */
diff --git a/src/styles/normalize.scss b/src/styles/normalize.scss
new file mode 100644
index 0000000..fe27fe8
--- /dev/null
+++ b/src/styles/normalize.scss
@@ -0,0 +1,353 @@
+@charset "utf-8";
+
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+ ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+ display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ margin: 0.67em 0;
+ font-size: 2em;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
+ border-bottom: none; /* 1 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+ border-style: none;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0; /* 2 */
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input {
+ /* 1 */
+ overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select {
+ /* 1 */
+ text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box; /* 1 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ color: inherit; /* 2 */
+ white-space: normal; /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/* Misc
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+ display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+ display: none;
+}
diff --git a/src/styles/spinner/dots.css b/src/styles/spinner/dots.css
new file mode 100644
index 0000000..33bef95
--- /dev/null
+++ b/src/styles/spinner/dots.css
@@ -0,0 +1,110 @@
+.dots-loader:not(:required) {
+ position: relative;
+ display: inline-block;
+ width: 7px;
+ height: 7px;
+ margin-bottom: 30px;
+ overflow: hidden;
+ text-indent: -9999px;
+ background: transparent;
+ border-radius: 100%;
+ box-shadow: #f86 -14px -14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ transform-origin: 50% 50%;
+ animation: dots-loader 5s infinite ease-in-out;
+}
+
+@keyframes dots-loader {
+ 0% {
+ box-shadow: #f86 -14px -14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ }
+
+ 8.33% {
+ box-shadow: #f86 14px -14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ }
+
+ 16.67% {
+ box-shadow: #f86 14px 14px 0 7px,
+ #fc6 14px 14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ }
+
+ 25% {
+ box-shadow: #f86 -14px 14px 0 7px,
+ #fc6 -14px 14px 0 7px,
+ #6d7 -14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ }
+
+ 33.33% {
+ box-shadow: #f86 -14px -14px 0 7px,
+ #fc6 -14px 14px 0 7px,
+ #6d7 -14px -14px 0 7px,
+ #4ae -14px -14px 0 7px;
+ }
+
+ 41.67% {
+ box-shadow: #f86 14px -14px 0 7px,
+ #fc6 -14px 14px 0 7px,
+ #6d7 -14px -14px 0 7px,
+ #4ae 14px -14px 0 7px;
+ }
+
+ 50% {
+ box-shadow: #f86 14px 14px 0 7px,
+ #fc6 -14px 14px 0 7px,
+ #6d7 -14px -14px 0 7px,
+ #4ae 14px -14px 0 7px;
+ }
+
+ 58.33% {
+ box-shadow: #f86 -14px 14px 0 7px,
+ #fc6 -14px 14px 0 7px,
+ #6d7 -14px -14px 0 7px,
+ #4ae 14px -14px 0 7px;
+ }
+
+ 66.67% {
+ box-shadow: #f86 -14px -14px 0 7px,
+ #fc6 -14px -14px 0 7px,
+ #6d7 -14px -14px 0 7px,
+ #4ae 14px -14px 0 7px;
+ }
+
+ 75% {
+ box-shadow: #f86 14px -14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px -14px 0 7px,
+ #4ae 14px -14px 0 7px;
+ }
+
+ 83.33% {
+ box-shadow: #f86 14px 14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae 14px 14px 0 7px;
+ }
+
+ 91.67% {
+ box-shadow: #f86 -14px 14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ }
+
+ 100% {
+ box-shadow: #f86 -14px -14px 0 7px,
+ #fc6 14px -14px 0 7px,
+ #6d7 14px 14px 0 7px,
+ #4ae -14px 14px 0 7px;
+ }
+}
diff --git a/src/styles/spinner/gauge.css b/src/styles/spinner/gauge.css
new file mode 100644
index 0000000..1b82a28
--- /dev/null
+++ b/src/styles/spinner/gauge.css
@@ -0,0 +1,104 @@
+.gauge-loader:not(:required) {
+ position: relative;
+ display: inline-block;
+ width: 64px;
+ height: 32px;
+ margin-bottom: 10px;
+ overflow: hidden;
+ text-indent: -9999px;
+ background: #6ca;
+ border-top-left-radius: 32px;
+ border-top-right-radius: 32px;
+}
+
+.gauge-loader:not(:required)::before {
+ position: absolute;
+ top: 5px;
+ left: 30px;
+ width: 4px;
+ height: 27px;
+ content: "";
+ background: white;
+ border-radius: 2px;
+ transform-origin: 50% 100%;
+ animation: gauge-loader 4000ms infinite ease;
+}
+
+.gauge-loader:not(:required)::after {
+ position: absolute;
+ top: 26px;
+ left: 26px;
+ width: 13px;
+ height: 13px;
+ content: "";
+ background: white;
+ -moz-border-radius: 8px;
+ -webkit-border-radius: 8px;
+ border-radius: 8px;
+}
+
+@keyframes gauge-loader {
+ 0% {
+ transform: rotate(-50deg);
+ }
+
+ 10% {
+ transform: rotate(20deg);
+ }
+
+ 20% {
+ transform: rotate(60deg);
+ }
+
+ 24% {
+ transform: rotate(60deg);
+ }
+
+ 40% {
+ transform: rotate(-20deg);
+ }
+
+ 54% {
+ transform: rotate(70deg);
+ }
+
+ 56% {
+ transform: rotate(78deg);
+ }
+
+ 58% {
+ transform: rotate(73deg);
+ }
+
+ 60% {
+ transform: rotate(75deg);
+ }
+
+ 62% {
+ transform: rotate(70deg);
+ }
+
+ 70% {
+ transform: rotate(-20deg);
+ }
+
+ 80% {
+ transform: rotate(20deg);
+ }
+
+ 83% {
+ transform: rotate(25deg);
+ }
+
+ 86% {
+ transform: rotate(20deg);
+ }
+
+ 89% {
+ transform: rotate(25deg);
+ }
+
+ 100% {
+ transform: rotate(-50deg);
+ }
+}
diff --git a/src/styles/spinner/inner-circles.css b/src/styles/spinner/inner-circles.css
new file mode 100644
index 0000000..0144da2
--- /dev/null
+++ b/src/styles/spinner/inner-circles.css
@@ -0,0 +1,51 @@
+.inner-circles-loader:not(:required) {
+ position: relative;
+ display: inline-block;
+ width: 50px;
+ height: 50px;
+ margin-bottom: 10px;
+ overflow: hidden;
+ text-indent: -9999px;
+ background: rgba(25, 165, 152, 0.5);
+ border-radius: 50%;
+ transform: translate3d(0, 0, 0);
+}
+
+.inner-circles-loader:not(:required)::before,
+.inner-circles-loader:not(:required)::after {
+ position: absolute;
+ top: 0;
+ display: inline-block;
+ width: 50px;
+ height: 50px;
+ content: "";
+ border-radius: 50%;
+}
+
+.inner-circles-loader:not(:required)::before {
+ left: 0;
+ background: #c7efcf;
+ transform-origin: 0 50%;
+ animation: inner-circles-loader 3s infinite;
+}
+
+.inner-circles-loader:not(:required)::after {
+ right: 0;
+ background: #eef5db;
+ transform-origin: 100% 50%;
+ animation: inner-circles-loader 3s 0.2s reverse infinite;
+}
+
+@keyframes inner-circles-loader {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 50% {
+ transform: rotate(360deg);
+ }
+
+ 100% {
+ transform: rotate(0deg);
+ }
+}
diff --git a/src/styles/spinner/plus.css b/src/styles/spinner/plus.css
new file mode 100644
index 0000000..af4516f
--- /dev/null
+++ b/src/styles/spinner/plus.css
@@ -0,0 +1,341 @@
+.plus-loader:not(:required) {
+ position: relative;
+ display: inline-block;
+ width: 48px;
+ height: 48px;
+ margin-bottom: 10px;
+ overflow: hidden;
+ text-indent: -9999px;
+ background: #f86;
+ -moz-border-radius: 24px;
+ -webkit-border-radius: 24px;
+ border-radius: 24px;
+ -moz-transform: rotateZ(90deg);
+ -ms-transform: rotateZ(90deg);
+ -webkit-transform: rotateZ(90deg);
+ transform: rotateZ(90deg);
+ -moz-transform-origin: 50% 50%;
+ -ms-transform-origin: 50% 50%;
+ -webkit-transform-origin: 50% 50%;
+ transform-origin: 50% 50%;
+ -moz-animation: plus-loader-background 3s infinite ease-in-out;
+ -webkit-animation: plus-loader-background 3s infinite ease-in-out;
+ animation: plus-loader-background 3s infinite ease-in-out;
+}
+
+.plus-loader:not(:required)::after {
+ position: absolute;
+ top: 0;
+ right: 50%;
+ width: 50%;
+ height: 100%;
+ content: "";
+ background: #f86;
+ -moz-border-radius: 24px 0 0 24px;
+ -webkit-border-radius: 24px;
+ border-radius: 24px 0 0 24px;
+ -moz-transform-origin: 100% 50%;
+ -ms-transform-origin: 100% 50%;
+ -webkit-transform-origin: 100% 50%;
+ transform-origin: 100% 50%;
+ -moz-animation: plus-loader-top 3s infinite linear;
+ -webkit-animation: plus-loader-top 3s infinite linear;
+ animation: plus-loader-top 3s infinite linear;
+}
+
+.plus-loader:not(:required)::before {
+ position: absolute;
+ top: 0;
+ right: 50%;
+ width: 50%;
+ height: 100%;
+ content: "";
+ background: #fc6;
+ -moz-border-radius: 24px 0 0 24px;
+ -webkit-border-radius: 24px;
+ border-radius: 24px 0 0 24px;
+ -moz-transform-origin: 100% 50%;
+ -ms-transform-origin: 100% 50%;
+ -webkit-transform-origin: 100% 50%;
+ transform-origin: 100% 50%;
+ -moz-animation: plus-loader-bottom 3s infinite linear;
+ -webkit-animation: plus-loader-bottom 3s infinite linear;
+ animation: plus-loader-bottom 3s infinite linear;
+}
+
+@keyframes plus-loader-top {
+ 2.5% {
+ background: #f86;
+ -moz-transform: rotateY(0deg);
+ -ms-transform: rotateY(0deg);
+ -webkit-transform: rotateY(0deg);
+ transform: rotateY(0deg);
+ -moz-animation-timing-function: ease-in;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 13.75% {
+ background: #ff430d;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 13.76% {
+ background: #ffae0d;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: ease-out;
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 25% {
+ background: #fc6;
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ transform: rotateY(180deg);
+ }
+
+ 27.5% {
+ background: #fc6;
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ transform: rotateY(180deg);
+ -moz-animation-timing-function: ease-in;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 41.25% {
+ background: #ffae0d;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 41.26% {
+ background: #2cc642;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: ease-out;
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 50% {
+ background: #6d7;
+ -moz-transform: rotateY(0deg);
+ -ms-transform: rotateY(0deg);
+ -webkit-transform: rotateY(0deg);
+ transform: rotateY(0deg);
+ }
+
+ 52.5% {
+ background: #6d7;
+ -moz-transform: rotateY(0deg);
+ -ms-transform: rotateY(0deg);
+ -webkit-transform: rotateY(0deg);
+ transform: rotateY(0deg);
+ -moz-animation-timing-function: ease-in;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 63.75% {
+ background: #2cc642;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 63.76% {
+ background: #1386d2;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: ease-out;
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 75% {
+ background: #4ae;
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ transform: rotateY(180deg);
+ }
+
+ 77.5% {
+ background: #4ae;
+ -moz-transform: rotateY(180deg);
+ -ms-transform: rotateY(180deg);
+ -webkit-transform: rotateY(180deg);
+ transform: rotateY(180deg);
+ -moz-animation-timing-function: ease-in;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 91.25% {
+ background: #1386d2;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 91.26% {
+ background: #ff430d;
+ -moz-transform: rotateY(90deg);
+ -ms-transform: rotateY(90deg);
+ -webkit-transform: rotateY(90deg);
+ transform: rotateY(90deg);
+ -moz-animation-timing-function: ease-in;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 100% {
+ background: #f86;
+ -moz-transform: rotateY(0deg);
+ -ms-transform: rotateY(0deg);
+ -webkit-transform: rotateY(0deg);
+ transform: rotateY(0deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+}
+
+@keyframes plus-loader-bottom {
+ 0% {
+ background: #fc6;
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 50% {
+ background: #fc6;
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 75% {
+ background: #4ae;
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 100% {
+ background: #4ae;
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+}
+
+@keyframes plus-loader-background {
+ 0% {
+ background: #f86;
+ -moz-transform: rotateZ(180deg);
+ -ms-transform: rotateZ(180deg);
+ -webkit-transform: rotateZ(180deg);
+ transform: rotateZ(180deg);
+ }
+
+ 25% {
+ background: #f86;
+ -moz-transform: rotateZ(180deg);
+ -ms-transform: rotateZ(180deg);
+ -webkit-transform: rotateZ(180deg);
+ transform: rotateZ(180deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 27.5% {
+ background: #6d7;
+ -moz-transform: rotateZ(90deg);
+ -ms-transform: rotateZ(90deg);
+ -webkit-transform: rotateZ(90deg);
+ transform: rotateZ(90deg);
+ }
+
+ 50% {
+ background: #6d7;
+ -moz-transform: rotateZ(90deg);
+ -ms-transform: rotateZ(90deg);
+ -webkit-transform: rotateZ(90deg);
+ transform: rotateZ(90deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 52.5% {
+ background: #6d7;
+ -moz-transform: rotateZ(0deg);
+ -ms-transform: rotateZ(0deg);
+ -webkit-transform: rotateZ(0deg);
+ transform: rotateZ(0deg);
+ }
+
+ 75% {
+ background: #6d7;
+ -moz-transform: rotateZ(0deg);
+ -ms-transform: rotateZ(0deg);
+ -webkit-transform: rotateZ(0deg);
+ transform: rotateZ(0deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+
+ 77.5% {
+ background: #f86;
+ -moz-transform: rotateZ(270deg);
+ -ms-transform: rotateZ(270deg);
+ -webkit-transform: rotateZ(270deg);
+ transform: rotateZ(270deg);
+ }
+
+ 100% {
+ background: #f86;
+ -moz-transform: rotateZ(270deg);
+ -ms-transform: rotateZ(270deg);
+ -webkit-transform: rotateZ(270deg);
+ transform: rotateZ(270deg);
+ -moz-animation-timing-function: step-start;
+ -webkit-animation-timing-function: step-start;
+ animation-timing-function: step-start;
+ }
+}
diff --git a/src/styles/themes/dark.scss b/src/styles/themes/dark.scss
new file mode 100644
index 0000000..f632560
--- /dev/null
+++ b/src/styles/themes/dark.scss
@@ -0,0 +1,4 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 暗黑之子主题(VIP群专享)
+ */
diff --git a/src/styles/themes/glory.scss b/src/styles/themes/glory.scss
new file mode 100644
index 0000000..cd56998
--- /dev/null
+++ b/src/styles/themes/glory.scss
@@ -0,0 +1,4 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 荣耀典藏主题(VIP群专享)
+ */
diff --git a/src/styles/themes/green.scss b/src/styles/themes/green.scss
new file mode 100644
index 0000000..4aff3b2
--- /dev/null
+++ b/src/styles/themes/green.scss
@@ -0,0 +1,4 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 绿荫操场主题(VIP群专享)
+ */
diff --git a/src/styles/themes/ocean.scss b/src/styles/themes/ocean.scss
new file mode 100644
index 0000000..835114b
--- /dev/null
+++ b/src/styles/themes/ocean.scss
@@ -0,0 +1,4 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 海洋之心主题(VIP群专享)
+ */
diff --git a/src/styles/transition.scss b/src/styles/transition.scss
new file mode 100644
index 0000000..7944c10
--- /dev/null
+++ b/src/styles/transition.scss
@@ -0,0 +1,21 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description vue过渡动画
+ */
+
+@charset "utf-8";
+
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+ transition: $base-transition;
+}
+
+.fade-transform-enter {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+
+.fade-transform-leave-to {
+ opacity: 0;
+ transform: translateX(30px);
+}
diff --git a/src/styles/vab.scss b/src/styles/vab.scss
new file mode 100644
index 0000000..d2da75d
--- /dev/null
+++ b/src/styles/vab.scss
@@ -0,0 +1,282 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局样式
+ */
+
+@charset "utf-8";
+
+@import "./normalize.scss";
+@import "./transition.scss";
+@import "./loading.scss";
+@import "./themes/ocean.scss";
+@import "./themes/green.scss";
+@import "./themes/glory.scss";
+@import "./themes/dark.scss";
+$base: ".vab";
+
+@mixin scrollbar {
+ max-height: 88vh;
+ margin-bottom: 0.5vh;
+ overflow-y: auto;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(144, 147, 153, 0.3);
+ border-radius: 10px;
+ }
+
+ &::-webkit-scrollbar-thumb:hover {
+ background-color: rgba(144, 147, 153, 0.3);
+ }
+}
+
+@mixin base-scrollbar {
+ &::-webkit-scrollbar {
+ width: 13px;
+ height: 13px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(0, 0, 0, 0.4);
+ background-clip: padding-box;
+ border: 3px solid transparent;
+ border-radius: 7px;
+ }
+
+ &::-webkit-scrollbar-thumb:hover {
+ background-color: rgba(0, 0, 0, 0.5);
+ }
+
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ &::-webkit-scrollbar-track:hover {
+ background-color: #f8fafc;
+ }
+}
+
+img {
+ object-fit: cover;
+}
+
+a {
+ color: $base-color-blue;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+html {
+ body {
+ position: relative;
+ height: 100vh;
+ padding: 0;
+ margin: 0;
+ font-family: Avenir, Helvetica, Arial, sans-serif;
+ font-size: $base-font-size-default;
+ color: #2c3e50;
+ background: #f6f8f9;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ @include base-scrollbar;
+
+ div {
+ @include base-scrollbar;
+ }
+
+ svg,
+ i {
+ &:hover {
+ opacity: 0.8;
+ }
+ }
+
+ /* el-tag开始 */
+ .el-tag + .el-tag {
+ margin-left: 10px;
+ }
+
+ /* el-tag结束 */
+
+ /* markdown编辑器开始 */
+ .editor-toolbar {
+ .no-mobile,
+ .fa-question-circle {
+ display: none;
+ }
+ }
+
+ /* markdown编辑器结束 */
+
+ /* 间隔线开始 */
+ .el-divider--horizontal {
+ margin: 10px 0 25px 0;
+
+ .el-divider__text {
+ display: -webkit-box;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ -webkit-line-clamp: 1;
+ -webkit-box-orient: vertical;
+ }
+ }
+
+ /* 间隔线结束 */
+
+ /* 大图展示开始 */
+ .el-image-viewer {
+ &__close {
+ .el-icon-circle-close {
+ color: $base-color-white;
+ }
+ }
+ }
+
+ /* 大图展示结束 */
+
+ .vue-admin-beautiful-wrapper {
+ .app-main-container {
+ @include base-scrollbar;
+
+ > [class*="-container"] {
+ padding: $base-padding;
+ background: $base-color-white;
+ }
+ }
+ }
+
+ /* 进度条开始 */
+ #nprogress {
+ position: fixed;
+ z-index: $base-z-index;
+
+ .bar {
+ background: $base-color-blue !important;
+ }
+
+ .peg {
+ box-shadow: 0 0 10px $base-color-blue, 0 0 5px $base-color-blue !important;
+ }
+ }
+
+ /* 进度条结束 */
+
+ /* 表格开始 */
+
+ .el-table {
+ .el-table__body-wrapper {
+ @include base-scrollbar;
+ }
+
+ th {
+ background: #f5f7fa;
+ }
+
+ td,
+ th {
+ position: relative;
+ box-sizing: border-box;
+ padding: 7.5px 0;
+
+ .cell {
+ font-size: $base-font-size-default;
+ font-weight: normal;
+ color: #606266;
+
+ .el-image {
+ width: 50px;
+ height: 50px;
+ border-radius: $base-border-radius;
+ }
+ }
+ }
+ }
+
+ /* 表格结束 */
+
+ /* 分页开始 */
+ .el-pagination {
+ padding: 2px 5px;
+ margin: 15px 0 0 0;
+ font-weight: normal;
+ color: $base-color-black;
+ text-align: center;
+ }
+
+ /* 分页结束 */
+
+ /* 菜单开始 */
+ .el-menu.el-menu--popup.el-menu--popup-right-start {
+ @include scrollbar;
+ }
+
+ .el-menu.el-menu--popup.el-menu--popup-bottom-start {
+ @include scrollbar;
+ }
+
+ .el-submenu__title i {
+ color: $base-color-white;
+ }
+
+ /* 菜单结束 */
+
+ /* 弹窗开始 */
+
+ .el-dialog,
+ .el-message-box {
+ &__body {
+ border-top: 1px solid $base-border-color;
+
+ .el-form {
+ padding-right: 30px;
+ }
+ }
+
+ &__footer {
+ padding: $base-padding;
+ text-align: right;
+ border-top: 1px solid $base-border-color;
+ }
+
+ &__content {
+ padding: 20px 20px 20px 20px;
+ }
+ }
+
+ /* 弹窗结束 */
+
+ /* 卡片开始 */
+ .el-card {
+ margin-bottom: 15px;
+
+ &__body {
+ padding: $base-padding;
+ }
+ }
+
+ /* 卡片结束 */
+
+ /* 下拉树样式-----------开始 */
+ .select-tree-popper {
+ .el-scrollbar {
+ .el-scrollbar__view {
+ .el-select-dropdown__item {
+ height: auto;
+ max-height: 274px;
+ padding: 0;
+ overflow-y: auto;
+ line-height: 26px;
+ }
+ }
+ }
+ }
+
+ /* 下拉树样式-----------结束 */
+ }
+}
diff --git a/src/styles/variables.scss b/src/styles/variables.scss
new file mode 100644
index 0000000..701998c
--- /dev/null
+++ b/src/styles/variables.scss
@@ -0,0 +1,82 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局主题变量配置,VIP文档内提供多种好看的配色方案(ant-design风格、layui风格、iview风格),请查看VIP文档主题配置篇
+ */
+/* stylelint-disable */
+@charset "utf-8";
+//框架默认主题色
+$base-color-default: #1890ff;
+//默认层级
+$base-z-index: 999;
+//横向布局纵向布局时菜单背景色
+$base-menu-background: #001529;
+//菜单文字颜色
+$base-menu-color: hsla(0, 0%, 100%, 0.95);
+//菜单选中文字颜色
+$base-menu-color-active: hsla(0, 0%, 100%, 0.95);
+//菜单选中背景色
+$base-menu-background-active: $base-color-default;
+//标题颜色
+$base-title-color: #fff;
+//字体大小配置
+$base-font-size-small: 12px;
+$base-font-size-default: 14px;
+$base-font-size-big: 16px;
+$base-font-size-bigger: 18px;
+$base-font-size-max: 22px;
+$base-font-color: #606266;
+$base-color-blue: $base-color-default;
+$base-color-green: #13ce66;
+$base-color-white: #fff;
+$base-color-black: #000;
+$base-color-yellow: #ffba00;
+$base-color-orange: #ff6700;
+$base-color-red: #ff4d4f;
+$base-color-gray: rgba(0, 0, 0, 0.65);
+$base-main-width: 1279px;
+$base-border-radius: 2px;
+$base-border-color: #dcdfe6;
+//输入框高度
+$base-input-height: 32px;
+//默认paddiing
+$base-padding: 20px;
+//默认阴影
+$base-box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+//横向布局时top-bar、logo、一级菜单的高度
+$base-top-bar-height: 65px;
+//纵向布局时logo的高度
+$base-logo-height: 75px;
+//顶部nav-bar的高度
+$base-nav-bar-height: 60px;
+//顶部多标签页tags-bar的高度
+$base-tags-bar-height: 55px;
+//顶部多标签页tags-bar中每一个item的高度
+$base-tag-item-height: 34px;
+//菜单li标签的高度
+$base-menu-item-height: 50px;
+//app-main的高度
+$base-app-main-height: calc(
+ 100vh - #{$base-nav-bar-height} - #{$base-tags-bar-height} - #{$base-padding} -
+ #{$base-padding} - 55px - 30px
+);
+//纵向布局时左侧导航未折叠时的宽度
+$base-left-menu-width: 256px;
+//纵向布局时左侧导航未折叠时右侧内容的宽度
+$base-right-content-width: calc(100% - #{$base-left-menu-width});
+//纵向布局时左侧导航已折叠时的宽度
+$base-left-menu-width-min: 65px;
+//纵向布局时左侧导航已折叠时右侧内容的宽度
+$base-right-content-width-min: calc(100% - #{$base-left-menu-width-min});
+//默认动画
+$base-transition: all 0.2s;
+//默认动画时长
+$base-transition-time: 0.2s;
+
+:export {
+ //菜单文字颜色变量导出
+ menu-color: $base-menu-color;
+ //菜单选中文字颜色变量导出
+ menu-color-active: $base-menu-color-active;
+ //菜单背景色变量导出
+ menu-background: $base-menu-background;
+}
diff --git a/src/utils/accessToken.js b/src/utils/accessToken.js
new file mode 100644
index 0000000..bb60de7
--- /dev/null
+++ b/src/utils/accessToken.js
@@ -0,0 +1,66 @@
+import { storage, tokenTableName } from "@/config/settings";
+import cookie from "js-cookie";
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 获取accessToken
+ * @returns {string|ActiveX.IXMLDOMNode|Promise|any|IDBRequest|MediaKeyStatus|FormDataEntryValue|Function|Promise}
+ */
+export function getAccessToken() {
+ if (storage) {
+ if ("localStorage" === storage) {
+ return localStorage.getItem(tokenTableName);
+ } else if ("sessionStorage" === storage) {
+ return sessionStorage.getItem(tokenTableName);
+ } else if ("cookie" === storage) {
+ return cookie.get(tokenTableName);
+ } else {
+ return localStorage.getItem(tokenTableName);
+ }
+ } else {
+ return localStorage.getItem(tokenTableName);
+ }
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 存储accessToken
+ * @param accessToken
+ * @returns {void|*}
+ */
+export function setAccessToken(accessToken) {
+ if (storage) {
+ if ("localStorage" === storage) {
+ return localStorage.setItem(tokenTableName, accessToken);
+ } else if ("sessionStorage" === storage) {
+ return sessionStorage.setItem(tokenTableName, accessToken);
+ } else if ("cookie" === storage) {
+ return cookie.set(tokenTableName, accessToken);
+ } else {
+ return localStorage.setItem(tokenTableName, accessToken);
+ }
+ } else {
+ return localStorage.setItem(tokenTableName, accessToken);
+ }
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 移除accessToken
+ * @returns {void|Promise}
+ */
+export function removeAccessToken() {
+ if (storage) {
+ if ("localStorage" === storage) {
+ return localStorage.removeItem(tokenTableName);
+ } else if ("sessionStorage" === storage) {
+ return sessionStorage.clear();
+ } else if ("cookie" === storage) {
+ return cookie.remove(tokenTableName);
+ } else {
+ return localStorage.removeItem(tokenTableName);
+ }
+ } else {
+ return localStorage.removeItem(tokenTableName);
+ }
+}
diff --git a/src/utils/clipboard.js b/src/utils/clipboard.js
new file mode 100644
index 0000000..bfb0c99
--- /dev/null
+++ b/src/utils/clipboard.js
@@ -0,0 +1,31 @@
+import Vue from "vue";
+import Clipboard from "clipboard";
+
+function clipboardSuccess() {
+ Vue.prototype.$baseMessage("复制成功", "success");
+}
+
+function clipboardError() {
+ Vue.prototype.$baseMessage("复制失败", "error");
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 复制数据
+ * @param text
+ * @param event
+ */
+export default function handleClipboard(text, event) {
+ const clipboard = new Clipboard(event.target, {
+ text: () => text,
+ });
+ clipboard.on("success", () => {
+ clipboardSuccess();
+ clipboard.destroy();
+ });
+ clipboard.on("error", () => {
+ clipboardError();
+ clipboard.destroy();
+ });
+ clipboard.onClick(event);
+}
diff --git a/src/utils/encrypt.js b/src/utils/encrypt.js
new file mode 100644
index 0000000..86abe2d
--- /dev/null
+++ b/src/utils/encrypt.js
@@ -0,0 +1,46 @@
+import { JSEncrypt } from "jsencrypt";
+import { getPublicKey } from "@/api/publicKey";
+
+const privateKey =
+ "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMFPa+v52FkSUXvcUnrGI/XzW3EpZRI0s9BCWJ3oNQmEYA5luWW5p8h0uadTIoTyYweFPdH4hveyxlwmS7oefvbIdiP+o+QIYW/R4Wjsb4Yl8MhR4PJqUE3RCy6IT9fM8ckG4kN9ECs6Ja8fQFc6/mSl5dJczzJO3k1rWMBhKJD/AgMBAAECgYEAucMakH9dWeryhrYoRHcXo4giPVJsH9ypVt4KzmOQY/7jV7KFQK3x//27UoHfUCak51sxFw9ek7UmTPM4HjikA9LkYeE7S381b4QRvFuf3L6IbMP3ywJnJ8pPr2l5SqQ00W+oKv+w/VmEsyUHr+k4Z+4ik+FheTkVWp566WbqFsECQQDjYaMcaKw3j2Zecl8T6eUe7fdaRMIzp/gcpPMfT/9rDzIQk+7ORvm1NI9AUmFv/FAlfpuAMrdL2n7p9uznWb7RAkEA2aP934kbXg5bdV0R313MrL+7WTK/qdcYxATUbMsMuWWQBoS5irrt80WCZbG48hpocJavLNjbtrjmUX3CuJBmzwJAOJg8uP10n/+ZQzjEYXh+BszEHDuw+pp8LuT/fnOy5zrJA0dO0RjpXijO3vuiNPVgHXT9z1LQPJkNrb5ACPVVgQJBALPeb4uV0bNrJDUb5RB4ghZnIxv18CcaqNIft7vuGCcFBAIPIRTBprR+RuVq+xHDt3sNXdsvom4h49+Hky1b0ksCQBBwUtVaqH6ztCtwUF1j2c/Zcrt5P/uN7IHAd44K0gIJc1+Csr3qPG+G2yoqRM8KVqLI8Z2ZYn9c+AvEE+L9OQY=";
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description RSA加密
+ * @param data
+ * @returns {Promise<{param: PromiseLike}|*>}
+ */
+export async function encryptedData(data) {
+ let publicKey = "";
+ const res = await getPublicKey();
+ publicKey = res.data.publicKey;
+ if (res.data.mockServer) {
+ publicKey = "";
+ }
+ if (publicKey == "") {
+ return data;
+ }
+ const encrypt = new JSEncrypt();
+ encrypt.setPublicKey(
+ `-----BEGIN PUBLIC KEY-----${publicKey}-----END PUBLIC KEY-----`
+ );
+ data = encrypt.encrypt(JSON.stringify(data));
+ return {
+ param: data,
+ };
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description RSA解密
+ * @param data
+ * @returns {PromiseLike}
+ */
+export function decryptedData(data) {
+ const decrypt = new JSEncrypt();
+ decrypt.setPrivateKey(
+ `-----BEGIN RSA PRIVATE KEY-----${privateKey}-----END RSA PRIVATE KEY-----`
+ );
+ data = decrypt.decrypt(JSON.stringify(data));
+ return data;
+}
diff --git a/src/utils/errorLog.js b/src/utils/errorLog.js
new file mode 100644
index 0000000..a36746c
--- /dev/null
+++ b/src/utils/errorLog.js
@@ -0,0 +1,25 @@
+import Vue from "vue";
+import store from "@/store";
+import { isArray, isString } from "@/utils/validate";
+import { errorLog } from "@/config/settings";
+
+const needErrorLog = errorLog;
+const checkNeed = () => {
+ const env = process.env.NODE_ENV;
+ if (isString(needErrorLog)) {
+ return env === needErrorLog;
+ }
+ if (isArray(needErrorLog)) {
+ return needErrorLog.includes(env);
+ }
+ return false;
+};
+if (checkNeed()) {
+ Vue.config.errorHandler = (err, vm, info) => {
+ console.error("vue-admin-beautiful错误拦截:", err, vm, info);
+ const url = window.location.href;
+ Vue.nextTick(() => {
+ store.dispatch("errorLog/addErrorLog", { err, vm, info, url });
+ });
+ };
+}
diff --git a/src/utils/handleRoutes.js b/src/utils/handleRoutes.js
new file mode 100644
index 0000000..e62c807
--- /dev/null
+++ b/src/utils/handleRoutes.js
@@ -0,0 +1,76 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description all模式渲染后端返回路由
+ * @param constantRoutes
+ * @returns {*}
+ */
+export function filterAllRoutes(constantRoutes) {
+ return constantRoutes.filter((route) => {
+ if (route.component) {
+ if (route.component === "Layout") {
+ route.component = (resolve) => require(["@/layouts"], resolve);
+ } else if (route.component === "EmptyLayout") {
+ route.component = (resolve) =>
+ require(["@/layouts/EmptyLayout"], resolve);
+ } else {
+ let path = "views/" + route.component;
+ if (
+ new RegExp("^/views/.*$").test(route.component) ||
+ new RegExp("^views/.*$").test(route.component)
+ ) {
+ path = route.component;
+ } else if (new RegExp("^/.*$").test(route.component)) {
+ path = "views" + route.component;
+ } else if (new RegExp("^@views/.*$").test(route.component)) {
+ path = route.component.slice(1);
+ } else {
+ path = "views/" + route.component;
+ }
+ route.component = (resolve) => require([`@/${path}`], resolve);
+ }
+ }
+ if (route.children && route.children.length) {
+ route.children = filterAllRoutes(route.children);
+ }
+ if (route.children && route.children.length === 0) {
+ delete route.children;
+ }
+ return true;
+ });
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断当前路由是否包含权限
+ * @param permissions
+ * @param route
+ * @returns {boolean|*}
+ */
+function hasPermission(permissions, route) {
+ if (route.meta && route.meta.permissions) {
+ return permissions.some((role) => route.meta.permissions.includes(role));
+ } else {
+ return true;
+ }
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description intelligence模式根据permissions数组拦截路由
+ * @param routes
+ * @param permissions
+ * @returns {[]}
+ */
+export function filterAsyncRoutes(routes, permissions) {
+ const finallyRoutes = [];
+ routes.forEach((route) => {
+ const item = { ...route };
+ if (hasPermission(permissions, item)) {
+ if (item.children) {
+ item.children = filterAsyncRoutes(item.children, permissions);
+ }
+ finallyRoutes.push(item);
+ }
+ });
+ return finallyRoutes;
+}
diff --git a/src/utils/index.js b/src/utils/index.js
new file mode 100644
index 0000000..749754d
--- /dev/null
+++ b/src/utils/index.js
@@ -0,0 +1,266 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 格式化时间
+ * @param time
+ * @param cFormat
+ * @returns {string|null}
+ */
+export function parseTime(time, cFormat) {
+ if (arguments.length === 0) {
+ return null;
+ }
+ const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
+ let date;
+ if (typeof time === "object") {
+ date = time;
+ } else {
+ if (typeof time === "string" && /^[0-9]+$/.test(time)) {
+ time = parseInt(time);
+ }
+ if (typeof time === "number" && time.toString().length === 10) {
+ time = time * 1000;
+ }
+ date = new Date(time);
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay(),
+ };
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key];
+ if (key === "a") {
+ return ["日", "一", "二", "三", "四", "五", "六"][value];
+ }
+ if (result.length > 0 && value < 10) {
+ value = "0" + value;
+ }
+ return value || 0;
+ });
+ return time_str;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 格式化时间
+ * @param time
+ * @param option
+ * @returns {string}
+ */
+export function formatTime(time, option) {
+ if (("" + time).length === 10) {
+ time = parseInt(time) * 1000;
+ } else {
+ time = +time;
+ }
+ const d = new Date(time);
+ const now = Date.now();
+
+ const diff = (now - d) / 1000;
+
+ if (diff < 30) {
+ return "刚刚";
+ } else if (diff < 3600) {
+ // less 1 hour
+ return Math.ceil(diff / 60) + "分钟前";
+ } else if (diff < 3600 * 24) {
+ return Math.ceil(diff / 3600) + "小时前";
+ } else if (diff < 3600 * 24 * 2) {
+ return "1天前";
+ }
+ if (option) {
+ return parseTime(time, option);
+ } else {
+ return (
+ d.getMonth() +
+ 1 +
+ "月" +
+ d.getDate() +
+ "日" +
+ d.getHours() +
+ "时" +
+ d.getMinutes() +
+ "分"
+ );
+ }
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 将url请求参数转为json格式
+ * @param url
+ * @returns {{}|any}
+ */
+export function paramObj(url) {
+ const search = url.split("?")[1];
+ if (!search) {
+ return {};
+ }
+ return JSON.parse(
+ '{"' +
+ decodeURIComponent(search)
+ .replace(/"/g, '\\"')
+ .replace(/&/g, '","')
+ .replace(/=/g, '":"')
+ .replace(/\+/g, " ") +
+ '"}'
+ );
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 父子关系的数组转换成树形结构数据
+ * @param data
+ * @returns {*}
+ */
+export function translateDataToTree(data) {
+ const parent = data.filter(
+ (value) => value.parentId === "undefined" || value.parentId == null
+ );
+ const children = data.filter(
+ (value) => value.parentId !== "undefined" && value.parentId != null
+ );
+ const translator = (parent, children) => {
+ parent.forEach((parent) => {
+ children.forEach((current, index) => {
+ if (current.parentId === parent.id) {
+ const temp = JSON.parse(JSON.stringify(children));
+ temp.splice(index, 1);
+ translator([current], temp);
+ typeof parent.children !== "undefined"
+ ? parent.children.push(current)
+ : (parent.children = [current]);
+ }
+ });
+ });
+ };
+ translator(parent, children);
+ return parent;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 树形结构数据转换成父子关系的数组
+ * @param data
+ * @returns {[]}
+ */
+export function translateTreeToData(data) {
+ const result = [];
+ data.forEach((item) => {
+ const loop = (data) => {
+ result.push({
+ id: data.id,
+ name: data.name,
+ parentId: data.parentId,
+ });
+ const child = data.children;
+ if (child) {
+ for (let i = 0; i < child.length; i++) {
+ loop(child[i]);
+ }
+ }
+ };
+ loop(item);
+ });
+ return result;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 10位时间戳转换
+ * @param time
+ * @returns {string}
+ */
+export function tenBitTimestamp(time) {
+ const date = new Date(time * 1000);
+ const y = date.getFullYear();
+ let m = date.getMonth() + 1;
+ m = m < 10 ? "" + m : m;
+ let d = date.getDate();
+ d = d < 10 ? "" + d : d;
+ let h = date.getHours();
+ h = h < 10 ? "0" + h : h;
+ let minute = date.getMinutes();
+ let second = date.getSeconds();
+ minute = minute < 10 ? "0" + minute : minute;
+ second = second < 10 ? "0" + second : second;
+ return y + "年" + m + "月" + d + "日 " + h + ":" + minute + ":" + second; //组合
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 13位时间戳转换
+ * @param time
+ * @returns {string}
+ */
+export function thirteenBitTimestamp(time) {
+ const date = new Date(time / 1);
+ const y = date.getFullYear();
+ let m = date.getMonth() + 1;
+ m = m < 10 ? "" + m : m;
+ let d = date.getDate();
+ d = d < 10 ? "" + d : d;
+ let h = date.getHours();
+ h = h < 10 ? "0" + h : h;
+ let minute = date.getMinutes();
+ let second = date.getSeconds();
+ minute = minute < 10 ? "0" + minute : minute;
+ second = second < 10 ? "0" + second : second;
+ return y + "年" + m + "月" + d + "日 " + h + ":" + minute + ":" + second; //组合
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 获取随机id
+ * @param length
+ * @returns {string}
+ */
+export function uuid(length = 32) {
+ const num = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+ let str = "";
+ for (let i = 0; i < length; i++) {
+ str += num.charAt(Math.floor(Math.random() * num.length));
+ }
+ return str;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description m到n的随机数
+ * @param m
+ * @param n
+ * @returns {number}
+ */
+export function random(m, n) {
+ return Math.floor(Math.random() * (m - n) + n);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description addEventListener
+ * @type {function(...[*]=)}
+ */
+export const on = (function () {
+ return function (element, event, handler, useCapture = false) {
+ if (element && event && handler) {
+ element.addEventListener(event, handler, useCapture);
+ }
+ };
+})();
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description removeEventListener
+ * @type {function(...[*]=)}
+ */
+export const off = (function () {
+ return function (element, event, handler, useCapture = false) {
+ if (element && event) {
+ element.removeEventListener(event, handler, useCapture);
+ }
+ };
+})();
diff --git a/src/utils/pageTitle.js b/src/utils/pageTitle.js
new file mode 100644
index 0000000..3f3c164
--- /dev/null
+++ b/src/utils/pageTitle.js
@@ -0,0 +1,14 @@
+import { title } from "@/config/settings";
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 设置标题
+ * @param pageTitle
+ * @returns {string}
+ */
+export default function getPageTitle(pageTitle) {
+ if (pageTitle) {
+ return `${pageTitle}-${title}`;
+ }
+ return `${title}`;
+}
diff --git a/src/utils/permission.js b/src/utils/permission.js
new file mode 100644
index 0000000..fa1c8f1
--- /dev/null
+++ b/src/utils/permission.js
@@ -0,0 +1,20 @@
+import store from "@/store";
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 检查权限
+ * @param value
+ * @returns {boolean}
+ */
+export default function checkPermission(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const permissions = store.getters["user/permissions"];
+ const permissionPermissions = value;
+
+ return permissions.some((role) => {
+ return permissionPermissions.includes(role);
+ });
+ } else {
+ return false;
+ }
+}
diff --git a/src/utils/request.js b/src/utils/request.js
new file mode 100644
index 0000000..b865a44
--- /dev/null
+++ b/src/utils/request.js
@@ -0,0 +1,144 @@
+import Vue from "vue";
+import axios from "axios";
+import {
+ baseURL,
+ contentType,
+ debounce,
+ invalidCode,
+ noPermissionCode,
+ requestTimeout,
+ successCode,
+ tokenName,
+ loginInterception,
+} from "@/config/settings";
+import store from "@/store";
+import qs from "qs";
+import router from "@/router";
+import { isArray } from "@/utils/validate";
+
+let loadingInstance;
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断当前url是否需要加loading
+ * @param {*} config
+ * @returns
+ */
+const needLoading = (config) => {
+ let status = false;
+ debounce.forEach((item) => {
+ if (Vue.prototype.$baseLodash.includes(config.url, item)) {
+ status = true;
+ }
+ });
+ return status;
+};
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 处理code异常
+ * @param {*} code
+ * @param {*} msg
+ */
+const handleCode = (code, msg) => {
+ switch (code) {
+ case invalidCode:
+ Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, "error");
+ store.dispatch("user/resetAccessToken").catch(() => {});
+ if (loginInterception) {
+ location.reload();
+ }
+ break;
+ case noPermissionCode:
+ router.push({ path: "/401" }).catch(() => {});
+ break;
+ default:
+ Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, "error");
+ break;
+ }
+};
+
+const instance = axios.create({
+ baseURL,
+ timeout: requestTimeout,
+ headers: {
+ "Content-Type": contentType,
+ },
+});
+
+instance.interceptors.request.use(
+ (config) => {
+ if (store.getters["user/accessToken"]) {
+ config.headers[tokenName] = store.getters["user/accessToken"];
+ }
+ //这里会过滤所有为空、0、false的key,如果不需要请自行注释
+ if (config.data)
+ config.data = Vue.prototype.$baseLodash.pickBy(
+ config.data,
+ Vue.prototype.$baseLodash.identity
+ );
+
+ if (
+ contentType === "application/x-www-form-urlencoded;charset=UTF-8" &&
+ config.data
+ ) {
+ config.data = qs.stringify(config.data);
+ }
+
+ if (needLoading(config)) {
+ loadingInstance = Vue.prototype.$baseLoading();
+ }
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ }
+);
+
+instance.interceptors.response.use(
+ (response) => {
+ if (loadingInstance) loadingInstance.close();
+
+ const { status, data, config } = response;
+ const { code, msg } = data;
+ // 操作正常Code数组
+ const codeVerificationArray = isArray(successCode)
+ ? [...successCode]
+ : [...[successCode]];
+ // 是否操作正常
+ if (codeVerificationArray.includes(code)) {
+ return data;
+ } else {
+ handleCode(code, msg);
+ return Promise.reject(
+ "vue-admin-beautiful请求异常拦截:" +
+ JSON.stringify({ url: config.url, code, msg }) || "Error"
+ );
+ }
+ },
+ (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);
+ } else {
+ let { message } = error;
+ if (message === "Network Error") {
+ message = "后端接口连接异常";
+ }
+ if (message.includes("timeout")) {
+ message = "后端接口请求超时";
+ }
+ 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);
+ }
+ }
+);
+
+export default instance;
diff --git a/src/utils/vab.js b/src/utils/vab.js
new file mode 100644
index 0000000..91854cd
--- /dev/null
+++ b/src/utils/vab.js
@@ -0,0 +1,180 @@
+import { loadingText, messageDuration, title } from "@/config/settings";
+import * as lodash from "lodash";
+import { Loading, Message, MessageBox, Notification } from "element-ui";
+import store from "@/store";
+import { getAccessToken } from "@/utils/accessToken";
+
+const accessToken = store.getters["user/accessToken"];
+const layout = store.getters["settings/layout"];
+
+const install = (Vue, opts = {}) => {
+ /* 全局accessToken */
+ Vue.prototype.$baseAccessToken = () => {
+ return accessToken || getAccessToken();
+ };
+ /* 全局标题 */
+ Vue.prototype.$baseTitle = (() => {
+ return title;
+ })();
+ /* 全局加载层 */
+ Vue.prototype.$baseLoading = (index, text) => {
+ let loading;
+ if (!index) {
+ loading = Loading.service({
+ lock: true,
+ text: text || loadingText,
+ background: "hsla(0,0%,100%,.8)",
+ });
+ } else {
+ loading = Loading.service({
+ lock: true,
+ text: text || loadingText,
+ spinner: "vab-loading-type" + index,
+ background: "hsla(0,0%,100%,.8)",
+ });
+ }
+ return loading;
+ };
+ /* 全局多彩加载层 */
+ Vue.prototype.$baseColorfullLoading = (index, text) => {
+ let loading;
+ if (!index) {
+ loading = Loading.service({
+ lock: true,
+ text: text || loadingText,
+ spinner: "dots-loader",
+ background: "hsla(0,0%,100%,.8)",
+ });
+ } else {
+ switch (index) {
+ case 1:
+ index = "dots";
+ break;
+ case 2:
+ index = "gauge";
+ break;
+ case 3:
+ index = "inner-circles";
+ break;
+ case 4:
+ index = "plus";
+ break;
+ }
+ loading = Loading.service({
+ lock: true,
+ text: text || loadingText,
+ spinner: index + "-loader",
+ background: "hsla(0,0%,100%,.8)",
+ });
+ }
+ return loading;
+ };
+ /* 全局Message */
+ Vue.prototype.$baseMessage = (message, type) => {
+ Message({
+ offset: 60,
+ showClose: true,
+ message: message,
+ type: type,
+ dangerouslyUseHTMLString: true,
+ duration: messageDuration,
+ });
+ };
+
+ /* 全局Alert */
+ Vue.prototype.$baseAlert = (content, title, callback) => {
+ MessageBox.alert(content, title || "温馨提示", {
+ confirmButtonText: "确定",
+ dangerouslyUseHTMLString: true,
+ callback: (action) => {
+ if (callback) {
+ callback();
+ }
+ },
+ });
+ };
+
+ /* 全局Confirm */
+ Vue.prototype.$baseConfirm = (content, title, callback1, callback2) => {
+ MessageBox.confirm(content, title || "温馨提示", {
+ confirmButtonText: "确定",
+ cancelButtonText: "取消",
+ closeOnClickModal: false,
+ type: "warning",
+ })
+ .then(() => {
+ if (callback1) {
+ callback1();
+ }
+ })
+ .catch(() => {
+ if (callback2) {
+ callback2();
+ }
+ });
+ };
+
+ /* 全局Notification */
+ Vue.prototype.$baseNotify = (message, title, type, position) => {
+ Notification({
+ title: title,
+ message: message,
+ position: position || "top-right",
+ type: type || "success",
+ duration: messageDuration,
+ });
+ };
+
+ /* 全局TableHeight */
+ Vue.prototype.$baseTableHeight = (formType) => {
+ let height = window.innerHeight;
+ let paddingHeight = 400;
+ const formHeight = 50;
+
+ if (layout === "vertical") {
+ paddingHeight = 340;
+ }
+
+ if ("number" == typeof formType) {
+ height = height - paddingHeight - formHeight * formType;
+ } else {
+ height = height - paddingHeight;
+ }
+ return height;
+ };
+
+ /* 全局map图层 */
+ Vue.prototype.$baseMap = () => {
+ return new maptalks.Map("map", {
+ center: [116.41348403785, 39.910843952376],
+ zoom: 12,
+ minZoom: 1,
+ maxZoom: 19,
+ spatialReference: {
+ projection: "baidu",
+ },
+ attribution: {
+ content: "© vue-admin-beautiful",
+ },
+ baseLayer: new maptalks.TileLayer("base", {
+ cssFilter: "sepia(100%) invert(90%)",
+ urlTemplate:
+ "http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1",
+ subdomains: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
+ attribution:
+ '© Baidu ',
+ }),
+ });
+ };
+
+ /* 全局lodash */
+ Vue.prototype.$baseLodash = lodash;
+ /* 全局事件总线 */
+ Vue.prototype.$baseEventBus = new Vue();
+};
+
+if (typeof window !== "undefined" && window.Vue) {
+ install(window.Vue);
+}
+
+export default install;
diff --git a/src/utils/validate.js b/src/utils/validate.js
new file mode 100644
index 0000000..45b1639
--- /dev/null
+++ b/src/utils/validate.js
@@ -0,0 +1,247 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判读是否为外链
+ * @param path
+ * @returns {boolean}
+ */
+export function isExternal(path) {
+ return /^(https?:|mailto:|tel:)/.test(path);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 校验密码是否小于6位
+ * @param str
+ * @returns {boolean}
+ */
+export function isPassword(str) {
+ return str.length >= 6;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否为数字
+ * @param value
+ * @returns {boolean}
+ */
+export function isNumber(value) {
+ const reg = /^[0-9]*$/;
+ return reg.test(value);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是名称
+ * @param value
+ * @returns {boolean}
+ */
+export function isName(value) {
+ const reg = /^[\u4e00-\u9fa5a-zA-Z0-9]+$/;
+ return reg.test(value);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否为IP
+ * @param ip
+ * @returns {boolean}
+ */
+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);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是传统网站
+ * @param url
+ * @returns {boolean}
+ */
+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);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是小写字母
+ * @param str
+ * @returns {boolean}
+ */
+export function isLowerCase(str) {
+ const reg = /^[a-z]+$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是大写字母
+ * @param str
+ * @returns {boolean}
+ */
+export function isUpperCase(str) {
+ const reg = /^[A-Z]+$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是大写字母开头
+ * @param str
+ * @returns {boolean}
+ */
+export function isAlphabets(str) {
+ const reg = /^[A-Za-z]+$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是字符串
+ * @param str
+ * @returns {boolean}
+ */
+export function isString(str) {
+ return typeof str === "string" || str instanceof String;
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是数组
+ * @param arg
+ * @returns {arg is any[]|boolean}
+ */
+export function isArray(arg) {
+ if (typeof Array.isArray === "undefined") {
+ return Object.prototype.toString.call(arg) === "[object Array]";
+ }
+ return Array.isArray(arg);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是端口号
+ * @param str
+ * @returns {boolean}
+ */
+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);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是手机号
+ * @param str
+ * @returns {boolean}
+ */
+export function isPhone(str) {
+ const reg = /^1\d{10}$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是身份证号(第二代)
+ * @param str
+ * @returns {boolean}
+ */
+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);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否是邮箱
+ * @param str
+ * @returns {boolean}
+ */
+export function isEmail(str) {
+ const reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否中文
+ * @param str
+ * @returns {boolean}
+ */
+export function isChina(str) {
+ const reg = /^[\u4E00-\u9FA5]{2,4}$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否为空
+ * @param str
+ * @returns {boolean}
+ */
+export function isBlank(str) {
+ return (
+ str == null ||
+ false ||
+ str === "" ||
+ str.trim() === "" ||
+ str.toLocaleLowerCase().trim() === "null"
+ );
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否为固话
+ * @param str
+ * @returns {boolean}
+ */
+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);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断是否为数字且最多两位小数
+ * @param str
+ * @returns {boolean}
+ */
+export function isNum(str) {
+ const reg = /^\d+(\.\d{1,2})?$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断经度 -180.0~+180.0(整数部分为0~180,必须输入1到5位小数)
+ * @param str
+ * @returns {boolean}
+ */
+export function isLongitude(str) {
+ const reg = /^[-|+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,5}|180\.0{1,5})$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 判断纬度 -90.0~+90.0(整数部分为0~90,必须输入1到5位小数)
+ * @param str
+ * @returns {boolean}
+ */
+export function isLatitude(str) {
+ const reg = /^[-|+]?([0-8]?\d{1}\.\d{1,5}|90\.0{1,5})$/;
+ return reg.test(str);
+}
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description rtsp校验,只要有rtsp://
+ * @param str
+ * @returns {boolean}
+ */
+export function isRTSP(str) {
+ const reg = /^rtsp:\/\/([a-z]{0,10}:.{0,10}@)?(\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])$/;
+ const reg1 = /^rtsp:\/\/([a-z]{0,10}:.{0,10}@)?(\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]):[0-9]{1,5}/;
+ const reg2 = /^rtsp:\/\/([a-z]{0,10}:.{0,10}@)?(\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(str) || reg1.test(str) || reg2.test(str);
+}
diff --git a/src/views/401.vue b/src/views/401.vue
new file mode 100644
index 0000000..e9c9970
--- /dev/null
+++ b/src/views/401.vue
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+
diff --git a/src/views/404.vue b/src/views/404.vue
new file mode 100644
index 0000000..eb714ac
--- /dev/null
+++ b/src/views/404.vue
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+
diff --git a/src/views/index/index.vue b/src/views/index/index.vue
new file mode 100644
index 0000000..ec7783b
--- /dev/null
+++ b/src/views/index/index.vue
@@ -0,0 +1,850 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 访问量
+
+
+
+
+ 日均访问量:
+
+
+
+
+
+
+
+
+
+ 授权数
+
+
+
+
+ 总授权数:
+
+
+
+
+
+
+
+
+ 词云
+
+
+
+
+ 词云数量:
+
+
+
+
+
+
+
+
+ GDP分布图
+
+
+
+
+
+
+
+
更新日志
+
部署时间:{{ updateTime }}
+
+
+
+
+ @vue/cli版本
+ {{ devDependencies["@vue/cli-service"] }}
+ vue版本
+ {{ dependencies["vue"] }}
+
+
+ vuex版本
+ {{ dependencies["vuex"] }}
+ vue-router版本
+ {{ dependencies["vue-router"] }}
+
+
+ element-ui版本
+ {{ dependencies["element-ui"] }}
+ axios版本
+ {{ dependencies["axios"] }}
+
+
+ eslint版本
+ {{ devDependencies["eslint"] }}
+ prettier版本
+ {{ devDependencies["prettier"] }}
+
+
+ sass版本
+ {{ devDependencies["sass"] }}
+ mockjs版本
+ {{ devDependencies["mockjs"] }}
+
+
+ zx-layouts版本
+ {{ dependencies["zx-layouts"] }}
+ lodash版本
+ {{ dependencies["lodash"] }}
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+ 更新日志
+
+
+
+ {{ activity.content }}
+
+
+
+
+
+
+
+ 其他信息
+
+
+
+
vue-admin-beautiful
+
+
+
+
+
+
+
+
+
+
+ 关于开发者
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
new file mode 100644
index 0000000..0456d31
--- /dev/null
+++ b/src/views/login/index.vue
@@ -0,0 +1,331 @@
+
+
+
+
+
+ 占位符
+
+
+
+ hello !
+ 欢迎来到{{ title }}!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+ 注册
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mall/goodsDetail/index.vue b/src/views/mall/goodsDetail/index.vue
new file mode 100644
index 0000000..550f13c
--- /dev/null
+++ b/src/views/mall/goodsDetail/index.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/src/views/mall/goodsList/index.vue b/src/views/mall/goodsList/index.vue
new file mode 100644
index 0000000..c9ce316
--- /dev/null
+++ b/src/views/mall/goodsList/index.vue
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+ 推荐
+ 缺货
+
+
+
+
+
{{ item.title }}
+
{{ item.description }}
+
+ ¥ {{ item.price }} 元
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mall/pay/components/Step1.vue b/src/views/mall/pay/components/Step1.vue
new file mode 100644
index 0000000..e7f25ef
--- /dev/null
+++ b/src/views/mall/pay/components/Step1.vue
@@ -0,0 +1,70 @@
+
+
+
+
+ 请务必仔细填写并核对
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 下一步
+
+
+
+
+
diff --git a/src/views/mall/pay/components/Step2.vue b/src/views/mall/pay/components/Step2.vue
new file mode 100644
index 0000000..c82780a
--- /dev/null
+++ b/src/views/mall/pay/components/Step2.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+ 确认转账后,资金将直接打入对方账户,无法退回。
+
+
+
+ {{ infoData.payAccount }}
+
+
+ {{ infoData.gatheringAccount }}
+
+
+ {{ infoData.gatheringName }}
+
+
+
+ {{ infoData.price }}
+
+
+
+
+
+
+
+
+ 提交
+
+ 上一步
+
+
+
+
+
diff --git a/src/views/mall/pay/components/Step3.vue b/src/views/mall/pay/components/Step3.vue
new file mode 100644
index 0000000..e90eb60
--- /dev/null
+++ b/src/views/mall/pay/components/Step3.vue
@@ -0,0 +1,101 @@
+
+
+
+
+
+ {{ infoData.payAccount }}
+
+
+ {{ infoData.gatheringAccount }}
+
+
+ {{ infoData.gatheringName }}
+
+
+
+ {{ infoData.price }}
+
+
+
+
+ 再转一笔
+
+
+
+
+
diff --git a/src/views/mall/pay/index.vue b/src/views/mall/pay/index.vue
new file mode 100644
index 0000000..225fc3f
--- /dev/null
+++ b/src/views/mall/pay/index.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/personalCenter/index.vue b/src/views/personalCenter/index.vue
new file mode 100644
index 0000000..2f5ea64
--- /dev/null
+++ b/src/views/personalCenter/index.vue
@@ -0,0 +1,23 @@
+
+
+
+ 个人简介
+ 基本设置
+ 安全设置
+ 安全设置
+
+
+
+
+
diff --git a/src/views/personnelManagement/menuManagement/components/MenuManagementEdit.vue b/src/views/personnelManagement/menuManagement/components/MenuManagementEdit.vue
new file mode 100644
index 0000000..e2d5b47
--- /dev/null
+++ b/src/views/personnelManagement/menuManagement/components/MenuManagementEdit.vue
@@ -0,0 +1,71 @@
+
+
+
+ 这里就不具体写了,请自行完善
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/personnelManagement/menuManagement/index.vue b/src/views/personnelManagement/menuManagement/index.vue
new file mode 100644
index 0000000..1a2a55a
--- /dev/null
+++ b/src/views/personnelManagement/menuManagement/index.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
diff --git a/src/views/personnelManagement/roleManagement/components/RoleManagementEdit.vue b/src/views/personnelManagement/roleManagement/components/RoleManagementEdit.vue
new file mode 100644
index 0000000..80cfa62
--- /dev/null
+++ b/src/views/personnelManagement/roleManagement/components/RoleManagementEdit.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/personnelManagement/roleManagement/index.vue b/src/views/personnelManagement/roleManagement/index.vue
new file mode 100644
index 0000000..434471e
--- /dev/null
+++ b/src/views/personnelManagement/roleManagement/index.vue
@@ -0,0 +1,157 @@
+
+
+
+ 演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
+
+
+
+
+ 添加
+
+
+ 批量删除
+
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/personnelManagement/userManagement/components/UserManagementEdit.vue b/src/views/personnelManagement/userManagement/components/UserManagementEdit.vue
new file mode 100644
index 0000000..ad364b4
--- /dev/null
+++ b/src/views/personnelManagement/userManagement/components/UserManagementEdit.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/personnelManagement/userManagement/index.vue b/src/views/personnelManagement/userManagement/index.vue
new file mode 100644
index 0000000..28e2f5c
--- /dev/null
+++ b/src/views/personnelManagement/userManagement/index.vue
@@ -0,0 +1,173 @@
+
+
+
+
+
+ 添加
+
+
+ 批量删除
+
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/register/index.vue b/src/views/register/index.vue
new file mode 100644
index 0000000..54627fb
--- /dev/null
+++ b/src/views/register/index.vue
@@ -0,0 +1,372 @@
+
+
+
+
+
+ 占位符
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ phoneCode }}
+
+
+
+
+
+
+
+
+
+ 注册
+
+
+ 登录
+
+
+
+
+
+
+
+
+
diff --git a/src/views/test/index.vue b/src/views/test/index.vue
new file mode 100644
index 0000000..c2bf779
--- /dev/null
+++ b/src/views/test/index.vue
@@ -0,0 +1,16 @@
+
+
+ 你可以在这里写demo
+
+
+
diff --git a/src/views/vab/backToTop/index.vue b/src/views/vab/backToTop/index.vue
new file mode 100644
index 0000000..b12bd5f
--- /dev/null
+++ b/src/views/vab/backToTop/index.vue
@@ -0,0 +1,22 @@
+
+
+
+ 测试滚轮显示返回顶部-{{ index }}
+
+
+
+
+
+
+
diff --git a/src/views/vab/betterScroll/index.vue b/src/views/vab/betterScroll/index.vue
new file mode 100644
index 0000000..e2ca9c1
--- /dev/null
+++ b/src/views/vab/betterScroll/index.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
diff --git a/src/views/vab/blacklist/index.vue b/src/views/vab/blacklist/index.vue
new file mode 100644
index 0000000..c5ab45c
--- /dev/null
+++ b/src/views/vab/blacklist/index.vue
@@ -0,0 +1,38 @@
+
+
+
+ vue-admin-beautiful禁止以下人员使用
+
+
+ 这世界嘲笑你的人有很多,你又不是圣人,干嘛对每个人都仁慈,面对无端的辱骂和攻击,你只能选择将他记在这里,时刻提醒自己。
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/card/index.vue b/src/views/vab/card/index.vue
new file mode 100644
index 0000000..d017153
--- /dev/null
+++ b/src/views/vab/card/index.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/TableEditor.vue b/src/views/vab/codeGenerator/components/TableEditor.vue
new file mode 100644
index 0000000..f36f4eb
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableEditor.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/TableExhibition.vue b/src/views/vab/codeGenerator/components/TableExhibition.vue
new file mode 100644
index 0000000..31fa051
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibition.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/TableExhibitionBody.vue b/src/views/vab/codeGenerator/components/TableExhibitionBody.vue
new file mode 100644
index 0000000..a800aac
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibitionBody.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+ {{ row[header.key] }}
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/TableExhibitionHeader.vue b/src/views/vab/codeGenerator/components/TableExhibitionHeader.vue
new file mode 100644
index 0000000..c755807
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibitionHeader.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/TableExhibitionQuery.vue b/src/views/vab/codeGenerator/components/TableExhibitionQuery.vue
new file mode 100644
index 0000000..73cb7eb
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibitionQuery.vue
@@ -0,0 +1,82 @@
+
+
+
+ 查看代码
+
+ 复制代码
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/snippetTable.js b/src/views/vab/codeGenerator/components/snippetTable.js
new file mode 100644
index 0000000..0ce4ba5
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/snippetTable.js
@@ -0,0 +1,154 @@
+import { genTableColumnSnippet } from "./snippetTableColumn";
+
+export const genTableSnippet = (headers = "getList") => {
+ return `
+
+
+
+ 添加
+ 修改
+ 批量删除
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+ ${genTableColumnSnippet(headers)}
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+`;
+};
diff --git a/src/views/vab/codeGenerator/components/snippetTableColumn.js b/src/views/vab/codeGenerator/components/snippetTableColumn.js
new file mode 100644
index 0000000..6b39700
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/snippetTableColumn.js
@@ -0,0 +1,40 @@
+const timeFieldNeedHandle = {
+ created_at: true,
+ create_time: true,
+ updated_at: true,
+ update_time: true,
+ start_time: true,
+ end_time: true,
+};
+const genTableColumnSnippetSimple = (key, label) => {
+ return ` `;
+};
+
+const genTabeleColumnSinppetTemplate = (key, label) => {
+ let val = "";
+ if (timeFieldNeedHandle[key]) {
+ val = `parseTime(row.${key})`;
+ } else {
+ val = `row.${key}`;
+ }
+ return `
+
+ {{ ${val} }}
+
+ `;
+};
+
+export const genTableColumnSnippet = (headers) => {
+ return headers
+ .filter((header) => {
+ return header.show;
+ })
+ .map((header) => {
+ if (timeFieldNeedHandle[header.key] || header.opt === "template") {
+ return genTabeleColumnSinppetTemplate(header.key, header.label);
+ } else {
+ return genTableColumnSnippetSimple(header.key, header.label);
+ }
+ })
+ .join("\n ");
+};
diff --git a/src/views/vab/codeGenerator/index.vue b/src/views/vab/codeGenerator/index.vue
new file mode 100644
index 0000000..3af1ebe
--- /dev/null
+++ b/src/views/vab/codeGenerator/index.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
diff --git a/src/views/vab/echarts/index.vue b/src/views/vab/echarts/index.vue
new file mode 100644
index 0000000..9c03214
--- /dev/null
+++ b/src/views/vab/echarts/index.vue
@@ -0,0 +1,652 @@
+
+
+
+
+
+ 柱状图
+
+
+
+
+
+
+
+ 环形图
+
+
+
+
+
+
+
+ 关系图
+
+
+
+
+
+
+
+
+ 中国地图
+
+
+
+
+
+
+
+ 世界地图
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/editor/index.vue b/src/views/vab/editor/index.vue
new file mode 100644
index 0000000..07264c5
--- /dev/null
+++ b/src/views/vab/editor/index.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 预览效果
+ 保存
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/element/index.vue b/src/views/vab/element/index.vue
new file mode 100644
index 0000000..b126c15
--- /dev/null
+++ b/src/views/vab/element/index.vue
@@ -0,0 +1,254 @@
+
+
+
+
+
+ element全部文档点这里
+
+
+
+
+
+ Tag 标签
+
+ 文档
+
+
+ 标签一
+ 标签二
+ 标签三
+ 标签四
+ 标签五
+ 标签一
+ 标签二
+ 标签三
+ 标签四
+ 标签五
+
+
+ 进度条
+
+ 文档
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 按钮
+
+ 文档
+
+
+ 默认按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+ 朴素按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+ 圆角按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+
+
+
+
+
+
+ 默认按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+
+
+
+ 搜索
+
+ 上传
+
+
+ 加载中
+
+
+ 文字链接
+
+ 文档
+
+
+
+ 默认链接
+
+ 主要链接
+ 成功链接
+ 警告链接
+ 危险链接
+ 信息链接
+ 默认链接
+ 主要链接
+ 成功链接
+ 警告链接
+ 危险链接
+ 信息链接
+ 无下划线
+ 有下划线
+
+ 头像
+
+ 文档
+
+
+
+
+ 页头
+
+ 文档
+
+
+
+
+ 面包屑
+
+ 文档
+
+
+
+ 首页
+ 活动管理
+ 活动列表
+ 活动详情
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/errorLog/components/ErrorTest.vue b/src/views/vab/errorLog/components/ErrorTest.vue
new file mode 100644
index 0000000..a64aadd
--- /dev/null
+++ b/src/views/vab/errorLog/components/ErrorTest.vue
@@ -0,0 +1,13 @@
+
+
+ {{ chuzhixinjiayou.chuzhixinjiayou }}
+
+
+
diff --git a/src/views/vab/errorLog/index.vue b/src/views/vab/errorLog/index.vue
new file mode 100644
index 0000000..67cf725
--- /dev/null
+++ b/src/views/vab/errorLog/index.vue
@@ -0,0 +1,28 @@
+
+
+
+ 这里会在顶部navbar上模拟一个控制台错误日志
+
+
+ 点击模拟一个chuzhixinjiayou的错误
+
+
+
+
+
+
diff --git a/src/views/vab/form/index.vue b/src/views/vab/form/index.vue
new file mode 100644
index 0000000..3b5bdb2
--- /dev/null
+++ b/src/views/vab/form/index.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 立即创建
+
+ 重置
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/icon/colorfulIcon.vue b/src/views/vab/icon/colorfulIcon.vue
new file mode 100644
index 0000000..f199989
--- /dev/null
+++ b/src/views/vab/icon/colorfulIcon.vue
@@ -0,0 +1,155 @@
+
+
+
+
+
+ 多彩图标在演示环境中使用的是cdn加速服务,开发时需存储到本地,使用方法可查看群文档,点击图标即可复制源码
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/icon/index.vue b/src/views/vab/icon/index.vue
new file mode 100644
index 0000000..1a162f2
--- /dev/null
+++ b/src/views/vab/icon/index.vue
@@ -0,0 +1,141 @@
+
+
+
+
+ 点击图标即可复制源码
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/icon/remixIcon.vue b/src/views/vab/icon/remixIcon.vue
new file mode 100644
index 0000000..9ca38c0
--- /dev/null
+++ b/src/views/vab/icon/remixIcon.vue
@@ -0,0 +1,153 @@
+
+
+
+
+
+ 小清新图标在演示环境中使用的是cdn加速服务,开发时需存储到本地,使用方法可查看群文档,点击图标即可复制源码,点击图标即可复制源码
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/imgComparison/index.vue b/src/views/vab/imgComparison/index.vue
new file mode 100644
index 0000000..dbd14b5
--- /dev/null
+++ b/src/views/vab/imgComparison/index.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/loading/index.vue b/src/views/vab/loading/index.vue
new file mode 100644
index 0000000..509edee
--- /dev/null
+++ b/src/views/vab/loading/index.vue
@@ -0,0 +1,71 @@
+
+
+ 传统loading
+ 默认效果
+ 效果1
+ 效果2
+ 效果3
+ 效果4
+ 效果5
+ 效果6
+ 效果7
+ 效果8
+ 效果9
+
+
+
+ 多彩loading
+
+ 效果1
+
+
+ 效果2
+
+
+ 效果3
+
+
+ 效果4
+
+
+
+
+
+
+
diff --git a/src/views/vab/lodash/index.vue b/src/views/vab/lodash/index.vue
new file mode 100644
index 0000000..9e0676e
--- /dev/null
+++ b/src/views/vab/lodash/index.vue
@@ -0,0 +1,211 @@
+
+
+
+
+
+
+ lodashjs官网
+
+
+
+
+
+
+
+ 去除数组array中的最后一个元素
+
+
+ this.$baseLodash.initial([1, 2, 3])
+
+ // => [1, 2]
+
+
+
+
+
+
+
+ 返回数组 array的第一个元素
+
+
+ this.$baseLodash.head([1, 2, 3])
+
+ // => 1
+
+
+
+
+
+
+ 合并数组
+
+ this.$baseLodash.concat([1],[2])
+
+ // => [1,2]
+
+
+
+
+
+
+ 左切片
+
+ this.$baseLodash.drop([1, 2, 3],2切除的数量)
+
+ // => [3]
+
+
+
+
+
+
+ 右切片
+
+ this.$baseLodash.dropRight([1, 2, 3],2切除的数量)
+
+ // => [1]
+
+
+
+
+
+
+ 修改拼接
+
+ this.$baseLodash.join(['a', 'b', 'c'], '~');
+
+ // => 'a~b~c'
+
+
+
+
+
+
+ 获取数组最后一个元素
+
+ this.$baseLodash.last(['a', 'b', 'c']);
+
+ // => 'c'
+
+
+
+
+
+
+ 数组去重
+
+ this.$baseLodash.uniq(['a', 'b', 'a']);
+
+ // => ['a','b']
+
+
+
+
+
+
+ 获取数组的最大值
+
+ this.$baseLodash.max([4, 2, 8, 6])
+
+ // => 8
+
+
+
+
+
+
+ 获取数组的最小值
+
+ this.$baseLodash.min([4, 2, 8, 6])
+
+ // => 2
+
+
+
+
+
+
+
+ 四舍五入(保留任意位小数)
+
+
+ this.$baseLodash.round(4.006,2保持几位小数)
+
+ // => 4.01
+
+
+
+
+
+
+ 数组内数据相加
+
+ this.$baseLodash.sum([4, 2, 8, 6])
+
+ // => 20
+
+
+
+
+
+
+ 返回随机数
+
+ this.$baseLodash.random(0, 5)
+
+ // => 0到5任意数
+
+
+
+
+
+
+ 返回数组内的随机数
+
+ this.$baseLodash.sample([1, 2, 3, 4])
+
+ // => 数组1到4任意数
+
+
+
+
+
+
+ 事件防抖动
+
+ this.$baseLodash.debounce(@click的事件,延迟的毫秒数)
+
+ // => 点击后多久不可以点击
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/magnifier/index.vue b/src/views/vab/magnifier/index.vue
new file mode 100644
index 0000000..733b48a
--- /dev/null
+++ b/src/views/vab/magnifier/index.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+ 放大镜1
+
+
+
+
+
+ 放大镜2
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/map/index.vue b/src/views/vab/map/index.vue
new file mode 100644
index 0000000..a493949
--- /dev/null
+++ b/src/views/vab/map/index.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
diff --git a/src/views/vab/markdown/index.vue b/src/views/vab/markdown/index.vue
new file mode 100644
index 0000000..b073566
--- /dev/null
+++ b/src/views/vab/markdown/index.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
diff --git a/src/views/vab/markdownEditor/index.vue b/src/views/vab/markdownEditor/index.vue
new file mode 100644
index 0000000..a8c5190
--- /dev/null
+++ b/src/views/vab/markdownEditor/index.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+ 增加文本
+ 增加图片
+
+
+
+
+ markdown转换html实时演示区域
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/more/index.vue b/src/views/vab/more/index.vue
new file mode 100644
index 0000000..f946ca4
--- /dev/null
+++ b/src/views/vab/more/index.vue
@@ -0,0 +1,142 @@
+
+
+
+ 看到这里,你心动了吗?如果你心动了那就加入我们的qq群吧(972435319),谢谢你愿意尊重作者的心血,希望我们每个人都变得优秀,如果你愿意跟随作者一起学习技术,作者QQ(1204505056白嫖党勿扰)
+
+
+
+
+
+ 开源版本
+
+ 永久免费 个人/商业使用
+
+
+
+
+ 永久开源免费,支持横纵布局切换
+ 保留控制台以及代码中的作者信息可免费商用
+
+ 开源地址
+
+ 支持白嫖,也请给个star
+
+
+ 提供讨论群专属文档,QQ群 972435319
+
+
+
+
+
+
+
+ VIP群
+
+ ¥100
+
+
+
+
+ 支持以上所有特权
+ 支持四种主题
+
+ vip群提供终身技术支持、专属文档及视频教程,可快速入手框架,包含打包优化,公共外框布局layout本地化及自定义教程等
+
+ QQ咨询 1204505056
+
+
+
+
+
+
+
+ 开源版授权 商业用途 完全自定义版权
+
+ ¥299
+
+
+
+
+ 支持以上所有特权,不包含VIP群
+
+ 可随意变更版权,但仅限自己团队使用,禁止恶意传播,禁止二次售卖
+
+ 包含开源基础版授权与开源集成版授权
+ 永久更新
+ 提供低价外包合作机会
+
+
+
+
+
+
+
+ PRO版
+
+ ¥599
+
+
+
+
+
+ 演示地址:
+
+ 点我
+
+
+ PRO独立版本与开源版本不同
+ 无开源版限制,无版权限制,无需额外配置,拿来即用
+ 免费加入vue-admin-beautifl github团队
+ 提供16种布局主题搭配
+ 图标使用方式大为简化
+ 支持国际化语言包、中英文无缝切换(此后将支持13国语言)
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/nested/menu1/index.vue b/src/views/vab/nested/menu1/index.vue
new file mode 100644
index 0000000..43702fc
--- /dev/null
+++ b/src/views/vab/nested/menu1/index.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/views/vab/nested/menu1/menu1-1/index.vue b/src/views/vab/nested/menu1/menu1-1/index.vue
new file mode 100644
index 0000000..4e4684b
--- /dev/null
+++ b/src/views/vab/nested/menu1/menu1-1/index.vue
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/src/views/vab/nested/menu1/menu1-1/menu1-1-1/index.vue b/src/views/vab/nested/menu1/menu1-1/menu1-1-1/index.vue
new file mode 100644
index 0000000..6b2f87c
--- /dev/null
+++ b/src/views/vab/nested/menu1/menu1-1/menu1-1-1/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/src/views/vab/permissions/index.vue b/src/views/vab/permissions/index.vue
new file mode 100644
index 0000000..5fb8548
--- /dev/null
+++ b/src/views/vab/permissions/index.vue
@@ -0,0 +1,166 @@
+
+
+
+ intelligence模式,前端根据permissions拦截路由(演示环境,默认使用此方案)
+
+
+
+
+
+ admin
+ editor
+ test
+
+
+
+
+
+ 切换权限
+
+
+
+ {{ JSON.stringify(permissions) }}
+
+
+
按钮级权限演示
+
+ 我是拥有["admin"]权限的按钮
+
+
+ 我是拥有["editor"]权限的按钮
+
+
+ 我是拥有["test"]权限的按钮
+
+
+
+
+ all模式,路由以及view文件引入全部交给后端(权限复杂,且随时变更,建议使用此方案)
+
+
+ settings.js配置authentication为all即可完全交由后端控制,mock中有后端接口示例,权限繁琐,有几十种权限的项目直接用这种,
+ 由于演示环境是mock数据模拟,可能无法展现此功能的配置,只做如下展示,便于您的理解
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.meta.affix }}
+
+
+
+
+
+
+ {{ scope.row.meta.noKeepAlive }}
+
+
+
+
+
+
+ {{ scope.row.meta.badge }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/player/index.vue b/src/views/vab/player/index.vue
new file mode 100644
index 0000000..916a9f4
--- /dev/null
+++ b/src/views/vab/player/index.vue
@@ -0,0 +1,73 @@
+
+
+
+ 视频地址采用cdn加速服务,开发时需部署到到本地,使用方法可查看群文档
+
+
+
+
+ 播放传统MP4
+
+
+
+
+
+ 播放m3u8,且不暴露视频地址
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/qrCode/index.vue b/src/views/vab/qrCode/index.vue
new file mode 100644
index 0000000..9579278
--- /dev/null
+++ b/src/views/vab/qrCode/index.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+ 二维码示例
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/smallComponents/index.vue b/src/views/vab/smallComponents/index.vue
new file mode 100644
index 0000000..e82d26d
--- /dev/null
+++ b/src/views/vab/smallComponents/index.vue
@@ -0,0 +1,110 @@
+
+
+
+
+ 小组件
+
+
+
+
+ snow
+
+
+
+
+
+
+
+ profile
+
+ 重载
+
+
+
+
+
+
+
+
+ charge
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/sticky/index.vue b/src/views/vab/sticky/index.vue
new file mode 100644
index 0000000..4de9cf2
--- /dev/null
+++ b/src/views/vab/sticky/index.vue
@@ -0,0 +1,314 @@
+
+
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
sticky
+
+
+
+
+
diff --git a/src/views/vab/table/components/TableEdit.vue b/src/views/vab/table/components/TableEdit.vue
new file mode 100644
index 0000000..aabae6f
--- /dev/null
+++ b/src/views/vab/table/components/TableEdit.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/table/index.vue b/src/views/vab/table/index.vue
new file mode 100644
index 0000000..579c70d
--- /dev/null
+++ b/src/views/vab/table/index.vue
@@ -0,0 +1,264 @@
+
+
+
+
+
+ 添加
+
+
+ 删除
+
+ baseMessage
+ baseAlert
+ baseConfirm
+ baseNotify
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+ {{ scope.$index + 1 }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.status }}
+
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/table/inlineEditTable.vue b/src/views/vab/table/inlineEditTable.vue
new file mode 100644
index 0000000..b0e7939
--- /dev/null
+++ b/src/views/vab/table/inlineEditTable.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ {{ scope.$index + 1 }}
+
+
+
+
+
+
+
+ 取消
+
+
+ {{ row.title }}
+
+
+
+
+
+
+ 保存
+
+
+ 编辑
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/tree/index.vue b/src/views/vab/tree/index.vue
new file mode 100644
index 0000000..67b4757
--- /dev/null
+++ b/src/views/vab/tree/index.vue
@@ -0,0 +1,478 @@
+
+
+
+
+
diff --git a/src/views/vab/upload/index.vue b/src/views/vab/upload/index.vue
new file mode 100644
index 0000000..f5c4cc9
--- /dev/null
+++ b/src/views/vab/upload/index.vue
@@ -0,0 +1,34 @@
+
+
+ 演示环境可能无法模拟上传
+
+
+ 模拟上传
+
+
+
+
+
diff --git a/src/views/vab/verify/index.vue b/src/views/vab/verify/index.vue
new file mode 100644
index 0000000..52fce2d
--- /dev/null
+++ b/src/views/vab/verify/index.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
diff --git a/src/views/vab/webSocket/index.vue b/src/views/vab/webSocket/index.vue
new file mode 100644
index 0000000..b2b30cc
--- /dev/null
+++ b/src/views/vab/webSocket/index.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+ webSocket连接{{ status }}!
+
+
+
+
+
+
+
+
+
+
+ 发送消息
+
+
+ {{ data }}
+
+
+
+
+
+
+
+
diff --git a/svgo.yml b/svgo.yml
new file mode 100644
index 0000000..31ca449
--- /dev/null
+++ b/svgo.yml
@@ -0,0 +1,4 @@
+plugins:
+ - removeAttrs:
+ attrs:
+ - "fill-rule"
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..da25fbb
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,216 @@
+const path = require("path");
+const {
+ publicPath,
+ assetsDir,
+ outputDir,
+ lintOnSave,
+ transpileDependencies,
+ title,
+ abbreviation,
+ devPort,
+ providePlugin,
+ build7z,
+ donation,
+} = require("./src/config/settings");
+const {
+ webpackBarName,
+ webpackBanner,
+ donationConsole,
+} = require("zx-layouts");
+
+if (donation) donationConsole();
+const { version, author } = require("./package.json");
+const Webpack = require("webpack");
+const WebpackBar = require("webpackbar");
+const FileManagerPlugin = require("filemanager-webpack-plugin");
+const dayjs = require("dayjs");
+const date = dayjs().format("YYYY_M_D");
+const time = dayjs().format("YYYY-M-D HH:mm:ss");
+const CompressionWebpackPlugin = require("compression-webpack-plugin");
+const productionGzipExtensions = ["html", "js", "css", "svg"];
+process.env.VUE_APP_TITLE = title || "vue-admin-beautiful";
+process.env.VUE_APP_AUTHOR = author || "chuzhixin 1204505056@qq.com";
+process.env.VUE_APP_UPDATE_TIME = time;
+process.env.VUE_APP_VERSION = version;
+
+const resolve = (dir) => {
+ return path.join(__dirname, dir);
+};
+
+const mockServer = () => {
+ if (process.env.NODE_ENV === "development") {
+ return require("./mock/mockServer.js");
+ } else {
+ return "";
+ }
+};
+
+module.exports = {
+ publicPath,
+ assetsDir,
+ outputDir,
+ lintOnSave,
+ transpileDependencies,
+ devServer: {
+ hot: true,
+ port: devPort,
+ open: true,
+ noInfo: false,
+ overlay: {
+ warnings: true,
+ errors: true,
+ },
+ after: mockServer(),
+ },
+ configureWebpack() {
+ return {
+ resolve: {
+ alias: {
+ "@": resolve("src"),
+ },
+ },
+ plugins: [
+ new Webpack.ProvidePlugin(providePlugin),
+ new WebpackBar({
+ name: webpackBarName,
+ }),
+ ],
+ };
+ },
+ chainWebpack(config) {
+ /* config.plugins.delete("preload");
+ config.plugins.delete("prefetch"); */
+ config.module
+ .rule("svg")
+ .exclude.add(resolve("src/remixIcon"))
+ .add(resolve("src/colorfulIcon"))
+ .end();
+
+ config.module
+ .rule("remixIcon")
+ .test(/\.svg$/)
+ .include.add(resolve("src/remixIcon"))
+ .end()
+ .use("svg-sprite-loader")
+ .loader("svg-sprite-loader")
+ .options({ symbolId: "remix-icon-[name]" })
+ .end();
+
+ config.module
+ .rule("colorfulIcon")
+ .test(/\.svg$/)
+ .include.add(resolve("src/colorfulIcon"))
+ .end()
+ .use("svg-sprite-loader")
+ .loader("svg-sprite-loader")
+ .options({ symbolId: "colorful-icon-[name]" })
+ .end();
+
+ config.when(process.env.NODE_ENV === "development", (config) => {
+ config.devtool("source-map");
+ });
+ config.when(process.env.NODE_ENV !== "development", (config) => {
+ config.performance.set("hints", false);
+ config.devtool("none");
+ config.optimization.splitChunks({
+ chunks: "all",
+ cacheGroups: {
+ libs: {
+ name: "chunk-libs",
+ test: /[\\/]node_modules[\\/]/,
+ priority: 10,
+ chunks: "initial",
+ },
+ elementUI: {
+ name: "chunk-elementUI",
+ priority: 20,
+ test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
+ },
+ fortawesome: {
+ name: "chunk-fortawesome",
+ priority: 20,
+ test: /[\\/]node_modules[\\/]_?@fortawesome(.*)/,
+ },
+ commons: {
+ name: "chunk-commons",
+ test: resolve("src/components"),
+ minChunks: 3,
+ priority: 5,
+ reuseExistingChunk: true,
+ },
+ },
+ });
+ config
+ .plugin("banner")
+ .use(Webpack.BannerPlugin, [`${webpackBanner}${time}`])
+ .end();
+ config
+ .plugin("compression")
+ .use(CompressionWebpackPlugin, [
+ {
+ filename: "[path].gz[query]",
+ algorithm: "gzip",
+ test: new RegExp(
+ "\\.(" + productionGzipExtensions.join("|") + ")$"
+ ),
+ threshold: 8192,
+ minRatio: 0.8,
+ },
+ ])
+ .end();
+ config.module
+ .rule("images")
+ .use("image-webpack-loader")
+ .loader("image-webpack-loader")
+ .options({
+ bypassOnDebug: true,
+ })
+ .end();
+ });
+
+ if (build7z) {
+ config.when(process.env.NODE_ENV === "production", (config) => {
+ config
+ .plugin("fileManager")
+ .use(FileManagerPlugin, [
+ {
+ onEnd: {
+ delete: [`./${outputDir}/video`, `./${outputDir}/data`],
+ archive: [
+ {
+ source: `./${outputDir}`,
+ destination: `./${outputDir}/${abbreviation}_${outputDir}_${date}.7z`,
+ },
+ ],
+ },
+ },
+ ])
+ .end();
+ });
+ }
+ },
+ runtimeCompiler: true,
+ productionSourceMap: false,
+ css: {
+ requireModuleExtension: true,
+ sourceMap: true,
+ loaderOptions: {
+ scss: {
+ /*sass-loader 8.0语法 */
+ //prependData: '@import "~@/styles/variables.scss";',
+
+ /*sass-loader 9.0写法,感谢github用户 shaonialife*/
+ additionalData(content, loaderContext) {
+ const { resourcePath, rootContext } = loaderContext;
+ const relativePath = path.relative(rootContext, resourcePath);
+ if (
+ relativePath.replace(/\\/g, "/") !== "src/styles/variables.scss"
+ ) {
+ return '@import "~@/styles/variables.scss";' + content;
+ }
+ return content;
+ },
+ },
+ },
+ },
+};
diff --git a/webstorm.config.js b/webstorm.config.js
new file mode 100644
index 0000000..6ec934d
--- /dev/null
+++ b/webstorm.config.js
@@ -0,0 +1,3 @@
+"use strict";
+const webpackConfig = require("@vue/cli-service/webpack.config.js");
+module.exports = webpackConfig;