commit 19d1a93109d551f97d38003bf0d24441d5135772
Author: 初志鑫 <1204505056@qq.com>
Date: Sun Jul 12 09:43:07 2020 +0800
deploy
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/.env.development b/.env.development
new file mode 100644
index 0000000..8651fae
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,2 @@
+NODE_ENV = development
+VUE_CLI_BABEL_TRANSPILE_MODULES = true
diff --git a/.env.preview b/.env.preview
new file mode 100644
index 0000000..98fc8f4
--- /dev/null
+++ b/.env.preview
@@ -0,0 +1 @@
+NODE_ENV = preview
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/.gitignore b/.gitignore
new file mode 100644
index 0000000..96314c5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+.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
diff --git a/.stylelintrc.js b/.stylelintrc.js
new file mode 100644
index 0000000..fa0cbfe
--- /dev/null
+++ b/.stylelintrc.js
@@ -0,0 +1,35 @@
+module.exports = {
+ extends: ["stylelint-config-standard", "stylelint-config-recess-order"],
+ rules: {
+ "at-rule-no-unknown": [
+ true,
+ {
+ ignoreAtRules: [
+ "mixin",
+ "extend",
+ "content",
+ "include",
+ "for",
+ "function",
+ "return",
+ ],
+ },
+ ],
+ "selector-pseudo-element-no-unknown": [
+ true,
+ {
+ ignorePseudoElements: ["v-deep"],
+ },
+ ],
+ "selector-pseudo-class-no-unknown": [
+ true,
+ {
+ ignorePseudoClasses: ["export"],
+ },
+ ],
+ indentation: 2,
+ "no-descending-specificity": null,
+ "declaration-colon-newline-after": null,
+ },
+ ignoreFiles: ["**/*.js", "dist/*.*", "node_modules", "**/*.ts"],
+};
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6e7511a
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,48 @@
+{
+ "[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,
+ "stylelint.enable": true,
+ "css.validate": false,
+ "less.validate": false,
+ "scss.validate": false,
+ "stylelint.autoFixOnSave": 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.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
+}
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.md b/README.md
new file mode 100644
index 0000000..3f13875
--- /dev/null
+++ b/README.md
@@ -0,0 +1,277 @@
+## 演示地址
+
+#### - [🚀 演示地址 1: vue-admin-beautiful (横向纵向布局无缝切换)](http://beautiful.panm.cn/vue-admin-beautiful/)
+
+#### - [🚀 国内备份地址: vue-admin-beautiful](https://chu1204505056.gitee.io/vue-admin-beautiful/)
+
+#### - [🚀 演示地址 2: vue-admin-clever (常规后台管理布局)](http://beautiful.panm.cn/vue-admin-clever/)
+
+## 安装
+
+```bash
+
+# 进入项目目录
+cd vue-admin-beautiful
+# 安装依赖
+cnpm i
+# 本地开发 启动项目
+cnpm run serve
+```
+
+## vue-admin-beautiful 前端讨论群-1 972435319(详细文档加群获取)
+
+不管您加或者不加 您都可以享受到开源的代码 感谢您的支持 感谢您的信任 群内提供 vue-admin-beautiful-template 基础版本 群内提供详细的基础文档 适合框架快速入门
+
+
+
+
+
+## 友情链接
+
+#### - [uView 文档(超棒的移动跨端框架,文档详细,上手容易)](https://uviewui.com/)
+
+#### - [uView 开源地址(uView UI,是 uni-app 生态优秀的 UI 框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水)](https://github.com/YanxinNet/uView/)
+
+#### - [Element UI 表单设计及代码生成器(可视化表单设计器,一键生成 element 表单)](https://github.com/JakHuang/form-generator/)
+
+#### - [luch-request(基于 Promise 开发的 uni-app 跨平台、项目级别的请求库,它有更小的体积,易用的 api,方便简单的自定义能力)](https://www.quanzhan.co/luch-request/)
+
+#### - [pl-table 完美解决 element 万级表格数据渲染卡顿问题](https://github.com/livelyPeng/pl-table)
+
+## 捐赠
+
+
+
+## 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" || process.env.NODE_ENV === "preview"
+ ? "vab-mock-server"
+ : "http://your.website.com",
+ //标题 (包括初次加载雪花屏的标题 页面的标题 浏览器的标题)
+ 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
diff --git a/README_DClOUD.md b/README_DClOUD.md
new file mode 100644
index 0000000..a5486f5
--- /dev/null
+++ b/README_DClOUD.md
@@ -0,0 +1,41 @@
+## 本项目地址
+
+#### - [🚀 演示地址 1 vue-admin-beautiful ](https://chu1204505056.gitee.io/vue-admin-beautiful/)
+
+#### - [🚀 演示地址 2 vue-admin-beautiful ](http://beautiful.panm.cn/vue-admin-beautiful/)
+
+#### - [🚀clever 版本 演示地址 vue-admin-beautiful ](http://beautiful.panm.cn/vue-admin-clever/)
+
+#### - [🚀 开源地址,感谢 star](https://github.com/chuzhixin/vue-admin-beautiful/)
+
+#### 学习讨论 QQ 群:972435319 群内提供基础版、集成版、clever 版本、详细文档与视频教程
+
+#### 付费群
+
+
+
+## 友情链接
+
+#### - [uView 文档(超棒的移动跨端框架,文档详细,上手容易)](https://uviewui.com/)
+
+#### - [uView 开源地址(uView UI,是 uni-app 生态优秀的 UI 框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水)](https://github.com/YanxinNet/uView/)
+
+#### - [luch-request(基于 Promise 开发的 uni-app 跨平台、项目级别的请求库,它有更小的体积,易用的 api,方便简单的自定义能力)](https://www.quanzhan.co/luch-request/)
+
+## 运行步骤,严格按步骤来
+
+```bash
+
+# 进入项目目录
+cd vue-admin-beautiful
+# 安装依赖,一定要cnpm i,别听网上乱七八糟的回答,本项目始终基于最新的package版本,cnpm不会出现任何问题,置于怎么安装cnpm自行百度
+cnpm i
+# 本地开发 启动项目
+cnpm run serve
+```
+
+#### 已付费置顶 烦请小号刷差评的放过 我也需要养家糊口 也祝您财运亨通 好不好用请看演示地址 保留版权信息可免费商用(页面所有版权信息不付费也可完全删除) ,群内提供详细的视频与文档教程,由于置顶费用较高,如有需要在本页加广告的朋友可以联系我 QQ 1204505056
+
+#### github 标星增长量统计
+
+[](https://github.com/chuzhixin/vue-admin-beautiful)
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..1b6f57d
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -e
+npm run build:preview
+cd dist
+touch .nojekyll
+git init
+git add -A
+git commit -m 'deploy'
+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/mock/controller/ad.js b/mock/controller/ad.js
new file mode 100644
index 0000000..226cac4
--- /dev/null
+++ b/mock/controller/ad.js
@@ -0,0 +1,41 @@
+const data = [
+ {
+ title:
+ "作为一个程序员,我迄今为止最骄傲的事情:2020年7月10日,vue/cli4作者蒋豪群采纳了我的对sass-loader 9.0全局注入变量的文档修改建议,以后全世界都能看到我的名字了,这远比vue-admin-beautiful更让我有成就感,感谢shaonialife的帮助。",
+ url: "https://github.com/vuejs/vue-cli/blob/master/docs/zh/guide/css.md",
+ },
+ {
+ title:
+ "近日发现一个名为OKMG芒果源码的网站公然出售vue-admin-beautiful的开源代码,在此向大家说明,框架开源版本永久免费,请勿上当受骗。",
+ url:
+ "//shang.qq.com/wpa/qunwpa?idkey=14f123ac6d4ef3122bbb60d4693f1d8c951a50be2296951efb12d5ab1642f36b",
+ },
+ {
+ title: "uView UI:全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
+ url: "https://uviewui.com/",
+ },
+ {
+ title:
+ "认认真真编程,踏踏实实做人;静坐常思己过,闲谈不论人非;希望使用vue-admin-beautiful框架的每个人,无论过程怎样,结局都是美好的。",
+ url:
+ "//shang.qq.com/wpa/qunwpa?idkey=14f123ac6d4ef3122bbb60d4693f1d8c951a50be2296951efb12d5ab1642f36b",
+ },
+ {
+ title: "vue-admin-beautiful前端讨论群-1:972435319",
+ url:
+ "//shang.qq.com/wpa/qunwpa?idkey=14f123ac6d4ef3122bbb60d4693f1d8c951a50be2296951efb12d5ab1642f36b",
+ },
+];
+export default [
+ {
+ url: "/ad/getList",
+ type: "get",
+ 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..f8a9d2f
--- /dev/null
+++ b/mock/controller/changeLog.js
@@ -0,0 +1,163 @@
+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",
+ },
+];
+
+export default [
+ {
+ url: "/changeLog/getList",
+ type: "post",
+ response: (config) => {
+ 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..6c5dba5
--- /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",
+];
+export default [
+ {
+ 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..8af174c
--- /dev/null
+++ b/mock/controller/goodsDetail.js
@@ -0,0 +1,42 @@
+import { mock } from "mockjs";
+
+export default [
+ {
+ 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..e50f6b9
--- /dev/null
+++ b/mock/controller/goodsList.js
@@ -0,0 +1,43 @@
+import { mock } from "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],
+ })
+ );
+}
+
+export default [
+ {
+ 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..2903095
--- /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",
+];
+export default [
+ {
+ 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..81a885e
--- /dev/null
+++ b/mock/controller/menuManagement.js
@@ -0,0 +1,51 @@
+export default [
+ {
+ 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..8526caa
--- /dev/null
+++ b/mock/controller/notice.js
@@ -0,0 +1,40 @@
+const data = [
+ {
+ title:
+ "认认真真编程,踏踏实实做人;静坐常思己过,闲谈不论人非;希望使用vue-admin-beautiful框架的每个人,无论过程怎样,结局都是美好的。。。",
+ closable: false,
+ type: "success",
+ },
+ {
+ title:
+ "作者寄语:感谢Star,感恩相遇,愿世间美好与我们环环相扣,加油!屏幕前的我们,打破桎梏,坚守初心。其实人生改变命运的机会并没有太多,我们并不是不优秀,我们也并不是一无是处,我们也希望驻足山巅被众人仰望,也许我们缺少的只是一个机会,缺少的只是生命中的导师,我希望这个框架帮助到更多的人,希望有一天,我们面试的时候不再胆怯,希望有一天别人看到的不仅仅是你的努力,还有你的功成名就,出人头地。",
+ closable: false,
+ type: "warning",
+ },
+ {
+ title:
+ "鸣谢:尤雨溪、蒋豪群、element-ui、唐金州、花裤衩、贤心、iView、uView的开源项目给我带来的很多的灵感,弱小的人才习惯嘲讽与否定,内心强大的人从不吝啬赞美与鼓励,人生在世,得到每个人的认可几乎是痴心妄想,我也只是一条略懂前端的咸鱼,可我仍一直怀揣着改变世界的梦想,希望我们每个人,不管过程怎样,结局都是美好的。",
+ closable: false,
+ type: "success",
+ },
+ {
+ title:
+ "随笔:我一直在寻找开源的真谛,我一直再想什么是开源,我一开始觉得免费就是开源,好像又不是。我理解的开源是:你也开源,我也开源,大家一起贡献,相互帮助。我最担心的事情是:我一个小人物,去伺候一众的伸手党,我想,这不是开源该有的氛围。我还太年轻,不懂什么是格局,我只知道,无私的帮助他人,能给我带来快乐,却不能给我带来收入,当然,有时候,快乐对我来说就已经足够了。可惜我是一个人,没有精力帮助到每一个人,可惜这个世界需要赚钱,才能过上平凡的生活,可惜了我的梦想,这个物欲横流的时代,理想主义的我们,即使内心坚决如铁,也似乎寸步难行。",
+ closable: false,
+ type: "success",
+ },
+];
+
+export default [
+ {
+ 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..c0f79f0
--- /dev/null
+++ b/mock/controller/personalCenter.js
@@ -0,0 +1,42 @@
+import { mock } from "mockjs";
+
+export default [
+ {
+ 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..a6c9036
--- /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",
+];
+export default [
+ {
+ 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..f341ef1
--- /dev/null
+++ b/mock/controller/roleManagement.js
@@ -0,0 +1,55 @@
+import { mock } from "mockjs";
+const totalCount = 2;
+const List = [
+ {
+ id: "@id",
+ permission: "admin",
+ },
+ {
+ id: "@id",
+ permission: "editor",
+ },
+];
+export default [
+ {
+ url: "/roleManagement/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: "/roleManagement/doEdit",
+ type: "post",
+ response: (config) => {
+ return {
+ code: 200,
+ msg: "模拟保存成功",
+ };
+ },
+ },
+ {
+ url: "/roleManagement/doDelete",
+ type: "post",
+ response: (config) => {
+ return {
+ code: 200,
+ msg: "模拟删除成功",
+ };
+ },
+ },
+];
diff --git a/mock/controller/router.js b/mock/controller/router.js
new file mode 100644
index 0000000..4286fe1
--- /dev/null
+++ b/mock/controller/router.js
@@ -0,0 +1,426 @@
+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: "excel",
+ component: "EmptyLayout",
+ redirect: "noRedirect",
+ name: "Excel",
+ meta: {
+ title: "Excel",
+ permissions: ["admin"],
+ },
+ children: [
+ {
+ path: "exportExcel",
+ component: "views/vab/excel/exportExcel",
+ name: "ExportExcel",
+ meta: { title: "导出Excel" },
+ },
+ {
+ path: "exportSelectedExcel",
+ component: "views/vab/excel/exportSelectExcel",
+ name: "ExportSelectedExcel",
+ meta: { title: "导出选中行" },
+ },
+ {
+ path: "exportMergeHeaderExcel",
+ component: "views/vab/excel/exportMergeHeaderExcel",
+ name: "ExportMergeHeaderExcel",
+ meta: { title: "导出合并" },
+ },
+ {
+ path: "uploadExcel",
+ component: "views/vab/excel/uploadExcel",
+ name: "UploadExcel",
+ meta: { title: "上传Excel" },
+ },
+ ],
+ },
+ {
+ 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" },
+ },
+ ],
+ },
+];
+export default [
+ {
+ 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..f1a61bd
--- /dev/null
+++ b/mock/controller/table.js
@@ -0,0 +1,88 @@
+import { mock } from "mockjs";
+import { handleRandomImage } from "../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)",
+ })
+ );
+}
+
+export default [
+ {
+ 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) => {
+ 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,
+ };
+ },
+ },
+ {
+ url: "/table/doEdit",
+ type: "post",
+ response: (config) => {
+ return {
+ code: 200,
+ msg: "模拟保存成功",
+ };
+ },
+ },
+ {
+ url: "/table/doDelete",
+ type: "post",
+ response: (config) => {
+ return {
+ code: 200,
+ msg: "模拟删除成功",
+ };
+ },
+ },
+];
diff --git a/mock/controller/tree.js b/mock/controller/tree.js
new file mode 100644
index 0000000..7b4da5e
--- /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: [],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+];
+export default [
+ {
+ 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..97f5ea9
--- /dev/null
+++ b/mock/controller/upload.js
@@ -0,0 +1,14 @@
+const data = [];
+export default [
+ {
+ 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..61e3034
--- /dev/null
+++ b/mock/controller/user.js
@@ -0,0 +1,95 @@
+import { handleRandomImage } from "../utils";
+const accessTokens = {
+ admin: "admin-accessToken",
+ editor: "editor-accessToken",
+ test: "test-accessToken",
+};
+
+export default [
+ {
+ url: "/publicKey",
+ type: "post",
+ response: (config) => {
+ return {
+ code: 200,
+ msg: "success",
+ data: {
+ mockServer: true,
+ },
+ };
+ },
+ },
+ {
+ 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..999332a
--- /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",
+ },
+];
+export default [
+ {
+ 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..45b3ba0
--- /dev/null
+++ b/mock/index.js
@@ -0,0 +1,35 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 导入所有 controller 模块,npm run serve时在node环境中自动输出controller文件夹下Mock接口,请勿修改。
+ */
+
+import { handleMockArray } from "./utils";
+import chalk from "chalk";
+import fs from "fs";
+import { baseURL, devPort, httpRequestFile } from "../src/config/settings";
+
+const mocks = [];
+const mockArray = handleMockArray();
+
+if (httpRequestFile) {
+ fs.writeFile("./http/mock.http", "", {}, function (err) {
+ if (err) throw err;
+ });
+}
+mockArray.forEach(async (item) => {
+ const obj = require(item).default;
+ await mocks.push(...obj);
+ if (httpRequestFile) {
+ obj.forEach((item) => {
+ fs.appendFile(
+ "./http/mock.http",
+ `\r\n###${item.url}###\r\POST http://localhost:${devPort}/${baseURL}${item.url}\r\nContent-Type: application/x-www-form-urlencoded\r\n###\r\n`,
+ (error) => {
+ if (error)
+ return chalk.red(`\n > 追加HTTP Request失败${error.message}`);
+ }
+ );
+ });
+ }
+});
+export default mocks;
diff --git a/mock/mockServer.js b/mock/mockServer.js
new file mode 100644
index 0000000..583bc3c
--- /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}}
+ */
+function registerRoutes(app) {
+ let mockLastIndex;
+ const { default: 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) {
+ 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) => {
+ require("@babel/register");
+ 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/static.js b/mock/static.js
new file mode 100644
index 0000000..3b6c3ec
--- /dev/null
+++ b/mock/static.js
@@ -0,0 +1,53 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 导入所有 controller 模块,浏览器环境中自动输出controller文件夹下Mock接口,请勿修改。
+ */
+import Mock from "mockjs";
+import { paramObj } from "../src/utils";
+
+const mocks = [];
+const files = require.context("./controller", false, /\.js$/);
+
+files.keys().forEach((key) => {
+ const obj = files(key).default;
+ 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/mock/utils/index.js b/mock/utils/index.js
new file mode 100644
index 0000000..2038ed9
--- /dev/null
+++ b/mock/utils/index.js
@@ -0,0 +1,39 @@
+import { Random } from "mockjs";
+import { join } from "path";
+import fs from "fs";
+
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 随机生成图片url。
+ * @param width
+ * @param height
+ * @returns {string}
+ */
+export 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 {[]}
+ */
+export 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;
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..718431b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,121 @@
+{
+ "name": "vue-admin-beautiful",
+ "version": "1.0.0",
+ "private": true,
+ "author": "chuzhixin",
+ "participants": [],
+ "homepage": "https://chu1204505056.gitee.io/vue-admin-beautiful",
+ "scripts": {
+ "serve": "npm run helper&&vue-cli-service serve",
+ "build": "npm run helper&&vue-cli-service build",
+ "build:preview": "npm run helper&&vue-cli-service build --mode preview",
+ "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 **/*.{vue,css,scss} --fix",
+ "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",
+ "helper": "node node_modules/zx-layouts"
+ },
+ "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.19.2",
+ "better-scroll": "^1.15.2",
+ "clipboard": "^2.0.6",
+ "codemirror": "^5.55.0",
+ "core-js": "^3.6.5",
+ "dayjs": "^1.8.29",
+ "echarts": "^4.8.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.19",
+ "maptalks": "^0.47.5",
+ "mapv": "^2.0.56",
+ "nprogress": "^0.2.0",
+ "qs": "^6.9.4",
+ "screenfull": "^5.0.2",
+ "vue": "^2.6.11",
+ "vue-amap": "^0.5.10",
+ "vue-echarts": "^5.0.0-beta.0",
+ "vue-qart": "^2.2.0",
+ "vue-router": "^3.3.4",
+ "vuedraggable": "^2.24.0",
+ "vuex": "^3.5.1",
+ "xlsx": "^0.16.3",
+ "zx-comparison": "^1.0.3",
+ "zx-count": "^0.3.7",
+ "zx-icon": "^1.1.1",
+ "zx-keel": "^0.9.4",
+ "zx-layouts": "^0.5.7",
+ "zx-magnifie": "^0.4.0",
+ "zx-markdown-editor": "^0.0.2",
+ "zx-player": "^0.9.6",
+ "zx-quill": "^0.0.2",
+ "zx-templates": "^0.0.10",
+ "zx-verify": "^0.0.2"
+ },
+ "devDependencies": {
+ "@babel/register": "^7.10.4",
+ "@vue/cli-plugin-babel": "^4.4.6",
+ "@vue/cli-plugin-eslint": "^4.4.6",
+ "@vue/cli-plugin-router": "^4.4.6",
+ "@vue/cli-plugin-vuex": "^4.4.6",
+ "@vue/cli-service": "^4.4.6",
+ "@vue/eslint-config-prettier": "^6.0.0",
+ "autoprefixer": "^9.8.5",
+ "babel-eslint": "^10.1.0",
+ "compression-webpack-plugin": "^4.0.0",
+ "eslint": "^7.4.0",
+ "eslint-plugin-prettier": "^3.1.4",
+ "eslint-plugin-vue": "^6.2.2",
+ "filemanager-webpack-plugin": "^2.0.5",
+ "husky": "^4.2.5",
+ "image-webpack-loader": "^6.0.0",
+ "increase-memory-limit": "^1.0.7",
+ "lint-staged": "^10.2.11",
+ "mockjs": "^1.1.0",
+ "plop": "^2.7.1",
+ "prettier": "^2.0.5",
+ "sass": "^1.26.10",
+ "sass-loader": "^9.0.2",
+ "script-loader": "^0.7.2",
+ "stylelint": "^13.6.1",
+ "stylelint-config-recess-order": "^2.0.4",
+ "stylelint-config-standard": "^20.0.0",
+ "stylelint-order": "^4.1.0",
+ "svg-sprite-loader": "^5.0.0",
+ "svgo": "^1.3.2",
+ "vue-template-compiler": "^2.6.11",
+ "webpackbar": "^4.0.0"
+ },
+ "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/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..a47ef4f
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ plugins: {
+ autoprefixer: {},
+ },
+};
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 0000000..841e661
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,15 @@
+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",
+ vueIndentScriptAndStyle: false,
+ 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..36e22da
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+ <%= 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..66ed8e9
--- /dev/null
+++ b/push.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -e
+git init
+git add -A
+git commit -m 'deploy'
+git push -f "https://${access_token}@github.com/chuzhixin/vue-admin-beautiful.git" master
+git push -f "https://${access_token}@gitee.com/chu1204505056/vue-admin-beautiful.git" master
+start "https://github.com/chuzhixin/vue-admin-beautiful"
+exec /bin/bash
+
+
+
+
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..e2ad31f
--- /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/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/face.js b/src/api/face.js
new file mode 100644
index 0000000..1bcec2e
--- /dev/null
+++ b/src/api/face.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function getList(data) {
+ return request({
+ url: "/face/list",
+ method: "post",
+ data,
+ });
+}
+
+export function doEdit(data) {
+ return request({
+ url: "/face/edit",
+ method: "post",
+ data,
+ });
+}
+
+export function doDelete(data) {
+ return request({
+ url: "/face/delete",
+ 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/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..167597a
--- /dev/null
+++ b/src/api/publicKey.js
@@ -0,0 +1,8 @@
+import request from "@/utils/request";
+
+export function getPublicKey(data) {
+ 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..65871c4
--- /dev/null
+++ b/src/api/user.js
@@ -0,0 +1,37 @@
+import request from "@/utils/request";
+import { encryptedData } from "@/utils/encrypt";
+import { loginRSA } from "@/config/settings";
+
+export async function login(data) {
+ if (loginRSA) {
+ data = await encryptedData(data);
+ }
+ return request({
+ url: "/login",
+ method: "post",
+ data,
+ });
+}
+
+export function getInfo(accessToken) {
+ return request({
+ url: "/userInfo",
+ method: "post",
+ data: {
+ 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/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..c40a7b4
--- /dev/null
+++ b/src/colorfulIcon/index.js
@@ -0,0 +1,17 @@
+import Vue from "vue";
+import ColorfullIcon from "@/components/ColorfullIcon";
+
+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..f8521cc
--- /dev/null
+++ b/src/colorfulIcon/svg/vab.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ColorfullIcon/index.vue b/src/components/ColorfullIcon/index.vue
new file mode 100644
index 0000000..6712055
--- /dev/null
+++ b/src/components/ColorfullIcon/index.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/JsonEditor/index.vue b/src/components/JsonEditor/index.vue
new file mode 100644
index 0000000..98eb21b
--- /dev/null
+++ b/src/components/JsonEditor/index.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/RemixIcon/index.vue b/src/components/RemixIcon/index.vue
new file mode 100644
index 0000000..f0c70d4
--- /dev/null
+++ b/src/components/RemixIcon/index.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SelectTree/index.vue b/src/components/SelectTree/index.vue
new file mode 100644
index 0000000..d683143
--- /dev/null
+++ b/src/components/SelectTree/index.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/UploadExcel/index.vue b/src/components/UploadExcel/index.vue
new file mode 100644
index 0000000..407c4ec
--- /dev/null
+++ b/src/components/UploadExcel/index.vue
@@ -0,0 +1,160 @@
+
+
+
+
+ 将excel文件拖拽到此处或
+
+
+ 点击上传
+
+
+
+
+
+
+
+
diff --git a/src/components/VabCharge/index.vue b/src/components/VabCharge/index.vue
new file mode 100644
index 0000000..14950e9
--- /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..40133fa
--- /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..0091cb8
--- /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..7b1b798
--- /dev/null
+++ b/src/components/VabQrCode/index.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
diff --git a/src/components/VabQueryForm/VabQueryFormBottomPanel.vue b/src/components/VabQueryForm/VabQueryFormBottomPanel.vue
new file mode 100644
index 0000000..dd51c11
--- /dev/null
+++ b/src/components/VabQueryForm/VabQueryFormBottomPanel.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/VabQueryForm/VabQueryFormLeftPanel.vue b/src/components/VabQueryForm/VabQueryFormLeftPanel.vue
new file mode 100644
index 0000000..64b41ff
--- /dev/null
+++ b/src/components/VabQueryForm/VabQueryFormLeftPanel.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/VabQueryForm/VabQueryFormRightPanel.vue b/src/components/VabQueryForm/VabQueryFormRightPanel.vue
new file mode 100644
index 0000000..25e2597
--- /dev/null
+++ b/src/components/VabQueryForm/VabQueryFormRightPanel.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/VabQueryForm/VabQueryFormTopPanel.vue b/src/components/VabQueryForm/VabQueryFormTopPanel.vue
new file mode 100644
index 0000000..0fd0198
--- /dev/null
+++ b/src/components/VabQueryForm/VabQueryFormTopPanel.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/VabQueryForm/index.vue b/src/components/VabQueryForm/index.vue
new file mode 100644
index 0000000..ca593d4
--- /dev/null
+++ b/src/components/VabQueryForm/index.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/VabQuill/index.vue b/src/components/VabQuill/index.vue
new file mode 100644
index 0000000..0530b38
--- /dev/null
+++ b/src/components/VabQuill/index.vue
@@ -0,0 +1,124 @@
+
+
+
+
+
diff --git a/src/components/VabSnow/index.vue b/src/components/VabSnow/index.vue
new file mode 100644
index 0000000..badcbb2
--- /dev/null
+++ b/src/components/VabSnow/index.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
diff --git a/src/components/VabSticky/index.vue b/src/components/VabSticky/index.vue
new file mode 100644
index 0000000..85e4582
--- /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..1d1840f
--- /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..b5d44b5
--- /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,
+ routesWhiteList,
+ progressBar,
+ recordRoute,
+} 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时,创建虚拟权限
+ store.dispatch("user/setPermissions", ["admin"]);
+ permissions = ["admin"];
+ } else {
+ permissions = await store.dispatch("user/getInfo");
+ }
+
+ 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..72c2d84
--- /dev/null
+++ b/src/config/settings.js
@@ -0,0 +1,99 @@
+/**
+ * @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" || process.env.NODE_ENV === "preview"
+ ? "vab-mock-server"
+ : "http://your.website.com",
+ //标题 (包括初次加载雪花屏的标题 页面的标题 浏览器的标题)
+ 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" ? 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",
+};
diff --git a/src/directive/drag/drag.js b/src/directive/drag/drag.js
new file mode 100644
index 0000000..e576866
--- /dev/null
+++ b/src/directive/drag/drag.js
@@ -0,0 +1,77 @@
+export default {
+ bind(el, binding, vnode) {
+ if (
+ el.querySelector(".el-dialog__header") &&
+ el.querySelector(".el-dialog")
+ ) {
+ const dialogHeaderEl = el.querySelector(".el-dialog__header");
+ const dragDom = el.querySelector(".el-dialog");
+ dialogHeaderEl.style.cssText += ";cursor:move;";
+ dragDom.style.cssText += ";top:0;";
+
+ const getStyle = (function () {
+ if (window.document.currentStyle) {
+ return (dom, attr) => dom.currentStyle[attr];
+ } else {
+ return (dom, attr) => getComputedStyle(dom, false)[attr];
+ }
+ })();
+
+ dialogHeaderEl.onmousedown = (e) => {
+ const disX = e.clientX - dialogHeaderEl.offsetLeft;
+ const disY = e.clientY - dialogHeaderEl.offsetTop;
+
+ const dragDomWidth = dragDom.offsetWidth;
+ const dragDomHeight = dragDom.offsetHeight;
+
+ const screenWidth = document.body.clientWidth;
+ const screenHeight = document.body.clientHeight;
+
+ const minDragDomLeft = dragDom.offsetLeft;
+ const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
+
+ const minDragDomTop = dragDom.offsetTop;
+ const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight;
+
+ let styL = getStyle(dragDom, "left");
+ let styT = getStyle(dragDom, "top");
+
+ if (styL.includes("%")) {
+ styL = +document.body.clientWidth * (+styL / 100);
+ styT = +document.body.clientHeight * (+styT / 100);
+ } else {
+ styL = +styL.replace(/\px/g, "");
+ styT = +styT.replace(/\px/g, "");
+ }
+
+ document.onmousemove = function (e) {
+ let left = e.clientX - disX;
+ let top = e.clientY - disY;
+
+ if (-left > minDragDomLeft) {
+ left = -minDragDomLeft;
+ } else if (left > maxDragDomLeft) {
+ left = maxDragDomLeft;
+ }
+
+ if (-top > minDragDomTop) {
+ top = -minDragDomTop;
+ } else if (top > maxDragDomTop) {
+ top = maxDragDomTop;
+ }
+
+ dragDom.style.cssText += `;left:${left + styL}px;top:${
+ top + styT
+ }px;`;
+
+ vnode.child.$emit("dragDialog");
+ };
+
+ document.onmouseup = function (e) {
+ document.onmousemove = null;
+ document.onmouseup = null;
+ };
+ };
+ }
+ },
+};
diff --git a/src/directive/drag/index.js b/src/directive/drag/index.js
new file mode 100644
index 0000000..1721e82
--- /dev/null
+++ b/src/directive/drag/index.js
@@ -0,0 +1,13 @@
+import drag from "./drag";
+
+const install = function (Vue) {
+ Vue.directive("drag", drag);
+};
+
+if (window.Vue) {
+ window["drag"] = drag;
+ Vue.use(install);
+}
+
+drag.install = install;
+export default drag;
diff --git a/src/directive/permissions/index.js b/src/directive/permissions/index.js
new file mode 100644
index 0000000..6cce43a
--- /dev/null
+++ b/src/directive/permissions/index.js
@@ -0,0 +1,13 @@
+import permissions from "./permissions";
+
+const install = function (Vue) {
+ Vue.directive("permissions", permissions);
+};
+
+if (window.Vue) {
+ window["permissions"] = permissions;
+ Vue.use(install);
+}
+
+permissions.install = install;
+export default permissions;
diff --git a/src/directive/permissions/permissions.js b/src/directive/permissions/permissions.js
new file mode 100644
index 0000000..9739e04
--- /dev/null
+++ b/src/directive/permissions/permissions.js
@@ -0,0 +1,18 @@
+import store from "@/store";
+
+export default {
+ inserted(el, binding) {
+ const { value } = binding;
+ const permissions = store.getters["user/permissions"];
+
+ if (value && value instanceof Array && value.length > 0) {
+ const hasPermission = permissions.some((role) => {
+ return value.includes(role);
+ });
+
+ if (!hasPermission) {
+ el.parentNode && el.parentNode.removeChild(el);
+ }
+ }
+ },
+};
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..278d3df
--- /dev/null
+++ b/src/layouts/components/Ad/index.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/src/layouts/components/index.js b/src/layouts/components/index.js
new file mode 100644
index 0000000..9c6c8f0
--- /dev/null
+++ b/src/layouts/components/index.js
@@ -0,0 +1,16 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 公共布局导出,已封装成npm,便于此后在线升级,当然也存在一定的弊端,给开发者自定义增加了一定的困难,如果您一定要进行高度自定义,请仔细阅读VIP群文档,layouts本地化篇
+ */
+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..88cca87
--- /dev/null
+++ b/src/layouts/index.vue
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..7752b35
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,20 @@
+import "core-js/stable";
+import "regenerator-runtime/runtime";
+import Vue from "vue";
+import App from "./App";
+import store from "./store";
+import router from "./router";
+import "./plugins";
+if (process.env.NODE_ENV === "preview") {
+ const { mockXHR } = require("../mock/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..12de74d
--- /dev/null
+++ b/src/plugins/index.js
@@ -0,0 +1,38 @@
+/* 公共引入,勿随意修改,修改时需经过确认 */
+import Vue from "vue";
+import "./element";
+import "./support";
+import "@/styles/vab.scss";
+import vab from "@/utils/vab";
+import "@/remixIcon";
+import "@/colorfulIcon";
+import "@/config/permission";
+import "@/utils/errorLog";
+import drag from "@/directive/drag";
+import permissions from "@/directive/permissions";
+import "./vabIcon";
+import VabCount from "zx-count";
+
+import VabQueryForm from "@/components/VabQueryForm";
+import VabQueryFormTopPanel from "@/components/VabQueryForm/VabQueryFormTopPanel";
+import VabQueryFormBottomPanel from "@/components/VabQueryForm/VabQueryFormBottomPanel";
+import VabQueryFormLeftPanel from "@/components/VabQueryForm/VabQueryFormLeftPanel";
+import VabQueryFormRightPanel from "@/components/VabQueryForm/VabQueryFormRightPanel";
+import VueAMap from "vue-amap";
+
+VueAMap.initAMapApiLoader({
+ key: "19c9d4c0e4b9611cd931a1e4f70788dc",
+ plugin: ["Autocomplete", "PlaceSearch", "PolyEditor", "CircleEditor"],
+ v: "1.4.4",
+});
+Vue.use(VueAMap);
+Vue.use(VabCount);
+Vue.use(permissions);
+Vue.use(drag);
+Vue.use(vab);
+
+Vue.component("vab-query-form", VabQueryForm);
+Vue.component("vab-query-form-left-panel", VabQueryFormLeftPanel);
+Vue.component("vab-query-form-right-panel", VabQueryFormRightPanel);
+Vue.component("vab-query-form-top-panel", VabQueryFormTopPanel);
+Vue.component("vab-query-form-bottom-panel", VabQueryFormBottomPanel);
diff --git a/src/plugins/support.js b/src/plugins/support.js
new file mode 100644
index 0000000..05df964
--- /dev/null
+++ b/src/plugins/support.js
@@ -0,0 +1,21 @@
+import { MessageBox } from "element-ui";
+import { 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 (process.env.NODE_ENV !== "development") {
+ document.writeln(
+ ''
+ );
+}
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..48fcf85
--- /dev/null
+++ b/src/plugins/vabKeel.js
@@ -0,0 +1,7 @@
+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..c506274
--- /dev/null
+++ b/src/plugins/vabMarkdownEditor.js
@@ -0,0 +1,4 @@
+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..6b20225
--- /dev/null
+++ b/src/plugins/vabVerify.js
@@ -0,0 +1,2 @@
+import VabVerify from "zx-verify";
+export default VabVerify;
diff --git a/src/remixIcon/index.js b/src/remixIcon/index.js
new file mode 100644
index 0000000..a34e9d9
--- /dev/null
+++ b/src/remixIcon/index.js
@@ -0,0 +1,17 @@
+import Vue from "vue";
+import RemixIcon from "@/components/RemixIcon";
+
+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..586115d
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,532 @@
+/**
+ * @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 { 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: "permissions",
+ name: "Permission",
+ component: () => import("@/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: () => 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: EmptyLayout,
+ redirect: "noRedirect",
+ name: "Map",
+ meta: {
+ title: "地图",
+ permissions: ["admin"],
+ },
+ children: [
+ {
+ path: "maptalks",
+ name: "Maptalks",
+ component: () => import("@/views/vab/map/index"),
+ meta: {
+ title: "maptalks地图",
+ permissions: ["admin"],
+ badge: "Pro",
+ },
+ },
+ {
+ path: "amap",
+ name: "Amap",
+ component: () => import("@/views/vab/map/amap"),
+ meta: { title: "高德地图", badge: "New" },
+ },
+ ],
+ },
+
+ {
+ 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: "excel",
+ component: EmptyLayout,
+ redirect: "noRedirect",
+ name: "Excel",
+ meta: {
+ title: "Excel",
+ permissions: ["admin"],
+ },
+ children: [
+ {
+ path: "exportExcel",
+ component: () => import("@/views/vab/excel/exportExcel"),
+ name: "ExportExcel",
+ meta: { title: "导出Excel" },
+ },
+ {
+ path: "exportSelectedExcel",
+ component: () => import("@/views/vab/excel/exportSelectExcel"),
+ name: "ExportSelectedExcel",
+ meta: { title: "导出选中行" },
+ },
+ {
+ path: "exportMergeHeaderExcel",
+ component: () => import("@/views/vab/excel/exportMergeHeaderExcel"),
+ name: "ExportMergeHeaderExcel",
+ meta: { title: "导出合并" },
+ },
+ {
+ path: "uploadExcel",
+ component: () => import("@/views/vab/excel/uploadExcel"),
+ name: "UploadExcel",
+ meta: { title: "上传Excel" },
+ },
+ ],
+ },
+ {
+ 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: "/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({
+ mode: routerMode,
+ scrollBehavior: () => ({
+ y: 0,
+ }),
+ routes: constantRoutes,
+});
+//注释的地方是允许路由重复点击,如果你觉得框架路由跳转规范太过严格可选择放开
+/*const originalPush = VueRouter.prototype.push;
+VueRouter.prototype.push = function push(location) {
+ return originalPush.call(this, location).catch((err) => err);
+};*/
+
+export function resetRouter() {
+ router.matcher = new VueRouter({
+ 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..c16acf6
--- /dev/null
+++ b/src/store/modules/routes.js
@@ -0,0 +1,48 @@
+/**
+ * @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) {
+ let accessedRoutes = [];
+ if (permissions.includes("admin")) {
+ accessedRoutes = asyncRoutes;
+ } else {
+ accessedRoutes = await filterAsyncRoutes(asyncRoutes, permissions);
+ }
+ commit("setRoutes", accessedRoutes);
+ return accessedRoutes;
+ },
+ 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..e73a03c
--- /dev/null
+++ b/src/store/modules/settings.js
@@ -0,0 +1,76 @@
+/**
+ * @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("BYUI-VUE-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..f7421f2
--- /dev/null
+++ b/src/store/modules/user.js
@@ -0,0 +1,100 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 登录、获取用户信息、退出登录、清除accessToken逻辑,不建议修改
+ */
+
+import Vue from "vue";
+import { getInfo, 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 getInfo({ commit, state }) {
+ const { data } = await getInfo(state.accessToken);
+ if (!data) {
+ Vue.prototype.$baseMessage("验证失败,请重新登录...", "error");
+ return false;
+ }
+ let { permissions, userName, avatar } = data;
+ if (permissions && userName) {
+ 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("tagsBar/delAllRoutes", null, { root: true });
+ 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..188ba5b
--- /dev/null
+++ b/src/styles/normalize.scss
@@ -0,0 +1,427 @@
+/*! normalize.scss v0.1.0 | MIT License | based on git.io/normalize */
+
+/**
+ * 1. Set default font family to sans-serif.
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
+ * user zoom.
+ */
+
+html {
+ font-family: sans-serif; /* 1 */
+ -ms-text-size-adjust: 100%; /* 2 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/**
+ * Remove default margin.
+ */
+
+body {
+ margin: 0;
+}
+
+/* HTML5 display definitions
+ ========================================================================== */
+
+/**
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
+ * and Firefox.
+ * Correct `block` display not defined for `main` in IE 11.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/**
+ * 1. Correct `inline-block` display not defined in IE 8/9.
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+ */
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block; /* 1 */
+ vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Prevent modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+/**
+ * Address `[hidden]` styling not present in IE 8/9/10.
+ * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
+ */
+
+[hidden],
+template {
+ display: none;
+}
+
+/* Links
+ ========================================================================== */
+
+/**
+ * Remove the gray background color from active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * Improve readability when focused and also mouse hovered in all browsers.
+ */
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+ */
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/**
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+ */
+
+b,
+strong {
+ font-weight: bold;
+}
+
+/**
+ * Address styling not present in Safari and Chrome.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/**
+ * Address variable `h1` font-size and margin within `section` and `article`
+ * contexts in Firefox 4+, Safari, and Chrome.
+ */
+
+h1 {
+ margin: 0.67em 0;
+ font-size: 2em;
+}
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+
+mark {
+ color: #000;
+ background: #ff0;
+}
+
+/**
+ * Address inconsistent and variable font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ */
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove border when inside `a` element in IE 8/9/10.
+ */
+
+img {
+ border: 0;
+}
+
+/**
+ * Correct overflow not hidden in IE 9/10/11.
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * Address margin not present in IE 8/9 and Safari.
+ */
+
+figure {
+ margin: 1em 40px;
+}
+
+/**
+ * Address differences between Firefox and other browsers.
+ */
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+/**
+ * Contain overflow in all browsers.
+ */
+
+pre {
+ overflow: auto;
+}
+
+/**
+ * Address odd `em`-unit font size rendering in all browsers.
+ */
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
+ * styling of `select`, unless a `border` property is set.
+ */
+
+/**
+ * 1. Correct color not being inherited.
+ * Known issue: affects color of disabled elements.
+ * 2. Correct font properties not being inherited.
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0; /* 3 */
+ font: inherit; /* 2 */
+ color: inherit; /* 1 */
+}
+
+/**
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
+ */
+
+button {
+ overflow: visible;
+}
+
+/**
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
+ * All other form control elements do not inherit `text-transform` values.
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
+ * Correct `select` style inheritance in Firefox.
+ */
+
+button,
+select {
+ text-transform: none;
+}
+
+/**
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ * and `video` controls.
+ * 2. Correct inability to style clickable `input` types in iOS.
+ * 3. Improve usability and consistency of cursor style between image-type
+ * `input` and others.
+ */
+
+button,
+html input[type="button"], /* 1 */
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button; /* 2 */
+ cursor: pointer; /* 3 */
+}
+
+/**
+ * Re-set default cursor for disabled elements.
+ */
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+/**
+ * Remove inner padding and border in Firefox 4+.
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+/**
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+
+input {
+ line-height: normal;
+}
+
+/**
+ * It's recommended that you don't attempt to style these elements.
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
+ *
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
+ * 2. Remove excess padding in IE 8/9/10.
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
+ * `font-size` values of the `input`, it causes the cursor style of the
+ * decrement button to change from `default` to `text`.
+ */
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
+ * (include `-moz` to future-proof).
+ */
+
+input[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box; /* 2 */
+ box-sizing: content-box;
+}
+
+/**
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
+ * Safari (but not Chrome) clips the cancel button when the search input has
+ * padding (and `textfield` appearance).
+ */
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * Define consistent border, margin, and padding.
+ */
+
+fieldset {
+ padding: 0.35em 0.625em 0.75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+
+/**
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+
+legend {
+ padding: 0; /* 2 */
+ border: 0; /* 1 */
+}
+
+/**
+ * Remove default vertical scrollbar in IE 8/9/10/11.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * Don't inherit the `font-weight` (applied by a rule above).
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+ */
+
+optgroup {
+ font-weight: bold;
+}
+
+/* Tables
+ ========================================================================== */
+
+/**
+ * Remove most spacing between table cells.
+ */
+
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+td,
+th {
+ padding: 0;
+}
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/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..a5e37fd
--- /dev/null
+++ b/src/styles/vab.scss
@@ -0,0 +1,289 @@
+/**
+ * @copyright chuzhixin 1204505056@qq.com
+ * @description 全局样式
+ */
+
+@charset "utf-8";
+
+@import "./normalize.scss";
+@import "./transition.scss";
+@import "./loading.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: "PingFang SC", Arial, "Microsoft YaHei", sans-serif;
+ font-size: $base-font-size-default;
+ background: #f6f8f9;
+
+ @include base-scrollbar;
+
+ div {
+ @include base-scrollbar;
+ }
+
+ svg,
+ i {
+ &:hover {
+ opacity: 0.8;
+ }
+ }
+
+ /* el-tag开始 */
+ .el-tag + .el-tag {
+ margin-left: 10px;
+ }
+
+ /* el-tag结束 */
+
+ /* 右侧主题配置、拷贝代码开始 */
+ .theme-bar-setting {
+ div {
+ border-bottom: 0 !important;
+
+ & + div {
+ border-top: 1px solid $base-color-white;
+ }
+
+ p {
+ padding: 0;
+ margin: 0;
+ }
+ }
+ }
+
+ /* 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 {
+ .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..75f06ea
--- /dev/null
+++ b/src/styles/variables.scss
@@ -0,0 +1,90 @@
+/**
+ * @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;
+}
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..740b175
--- /dev/null
+++ b/src/utils/encrypt.js
@@ -0,0 +1,47 @@
+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;
+ if (publicKey.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..1b037da
--- /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.str.slice(2);
+ } 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..a8e90f2
--- /dev/null
+++ b/src/utils/request.js
@@ -0,0 +1,119 @@
+import axios from "axios";
+import {
+ baseURL,
+ contentType,
+ invalidCode,
+ messageDuration,
+ noPermissionCode,
+ requestTimeout,
+ successCode,
+ tokenName,
+ debounce,
+} from "@/config/settings";
+import { Loading, Message } from "element-ui";
+import store from "@/store";
+import qs from "qs";
+import router from "@/router";
+import _ from "lodash";
+
+const service = axios.create({
+ baseURL,
+ timeout: requestTimeout,
+ headers: {
+ "Content-Type": contentType,
+ },
+});
+let loadingInstance;
+service.interceptors.request.use(
+ (config) => {
+ if (store.getters["user/accessToken"]) {
+ config.headers[tokenName] = store.getters["user/accessToken"];
+ }
+ if (config.data) {
+ config.data = _.pickBy(config.data, _.identity);
+ }
+ if (process.env.NODE_ENV !== "test") {
+ if (contentType === "application/x-www-form-urlencoded;charset=UTF-8") {
+ if (config.data && !config.data.param) {
+ config.data = qs.stringify(config.data);
+ }
+ }
+ }
+ const needLoading = () => {
+ let status = false;
+ debounce.forEach((item) => {
+ if (_.includes(config.url, item)) {
+ status = true;
+ }
+ });
+ return status;
+ };
+ if (needLoading()) {
+ loadingInstance = Loading.service();
+ }
+
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ }
+);
+
+const errorMsg = (message) => {
+ return Message({
+ message: message,
+ type: "error",
+ duration: messageDuration,
+ });
+};
+
+service.interceptors.response.use(
+ (response) => {
+ if (loadingInstance) {
+ loadingInstance.close();
+ }
+ const { status, data, config } = response;
+ const { code, msg } = data;
+ if (code !== successCode) {
+ switch (code) {
+ case invalidCode:
+ errorMsg(msg || `后端接口${code}异常`);
+ store.dispatch("user/resetAccessToken");
+ break;
+ case noPermissionCode:
+ router.push({
+ path: "/401",
+ });
+ break;
+ default:
+ errorMsg(msg || `后端接口${code}异常`);
+ break;
+ }
+ return Promise.reject(
+ "vue-admin-beautiful请求异常拦截:" +
+ JSON.stringify({ url: config.url, code, msg }) || "Error"
+ );
+ } else {
+ return data;
+ }
+ },
+ (error) => {
+ if (loadingInstance) {
+ loadingInstance.close();
+ }
+ /*网络连接过程异常处理*/
+ let { message } = error;
+ if (message == "Network Error") {
+ message = "后端接口连接异常";
+ }
+ if (message.includes("timeout")) {
+ message = "后端接口请求超时";
+ }
+ if (message.includes("Request failed with status code")) {
+ message = "后端接口" + message.substr(message.length - 3) + "异常";
+ }
+ errorMsg(message || "后端接口未知异常");
+ return Promise.reject(error);
+ }
+);
+export default service;
diff --git a/src/utils/vab.js b/src/utils/vab.js
new file mode 100644
index 0000000..3b82a87
--- /dev/null
+++ b/src/utils/vab.js
@@ -0,0 +1,192 @@
+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, callback) => {
+ 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)",
+ });
+ }
+ if (callback) {
+ callback(loading);
+ } else {
+ setTimeout(() => {
+ loading.close();
+ }, messageDuration);
+ }
+ };
+ /* 全局多彩加载层 */
+ Vue.prototype.$baseColorfullLoading = (index, text, callback) => {
+ 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)",
+ });
+ }
+ if (callback) {
+ callback(loading);
+ } else {
+ setTimeout(() => {
+ loading.close();
+ }, messageDuration);
+ }
+ };
+ /* 全局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/vendor/ExportExcel.js b/src/vendor/ExportExcel.js
new file mode 100644
index 0000000..ca927b7
--- /dev/null
+++ b/src/vendor/ExportExcel.js
@@ -0,0 +1,216 @@
+import { saveAs } from "file-saver";
+import XLSX from "xlsx";
+
+function generateArray(table) {
+ let out = [];
+ let rows = table.querySelectorAll("tr");
+ let ranges = [];
+ for (let R = 0; R < rows.length; ++R) {
+ let outRow = [];
+ let row = rows[R];
+ let columns = row.querySelectorAll("td");
+ for (let C = 0; C < columns.length; ++C) {
+ let cell = columns[C];
+ let colspan = cell.getAttribute("colspan");
+ let rowspan = cell.getAttribute("rowspan");
+ let cellValue = cell.innerText;
+ if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
+
+ ranges.forEach(function (range) {
+ if (
+ R >= range.s.r &&
+ R <= range.e.r &&
+ outRow.length >= range.s.c &&
+ outRow.length <= range.e.c
+ ) {
+ for (let i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
+ }
+ });
+
+ if (rowspan || colspan) {
+ rowspan = rowspan || 1;
+ colspan = colspan || 1;
+ ranges.push({
+ s: {
+ r: R,
+ c: outRow.length,
+ },
+ e: {
+ r: R + rowspan - 1,
+ c: outRow.length + colspan - 1,
+ },
+ });
+ }
+
+ outRow.push(cellValue !== "" ? cellValue : null);
+
+ if (colspan) for (let k = 0; k < colspan - 1; ++k) outRow.push(null);
+ }
+ out.push(outRow);
+ }
+ return [out, ranges];
+}
+
+function datenum(v, date1904) {
+ if (date1904) v += 1462;
+ let epoch = Date.parse(v);
+ return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
+}
+
+function sheet_from_array_of_arrays(data, opts) {
+ let ws = {};
+ let range = {
+ s: {
+ c: 10000000,
+ r: 10000000,
+ },
+ e: {
+ c: 0,
+ r: 0,
+ },
+ };
+ for (let R = 0; R != data.length; ++R) {
+ for (let C = 0; C != data[R].length; ++C) {
+ if (range.s.r > R) range.s.r = R;
+ if (range.s.c > C) range.s.c = C;
+ if (range.e.r < R) range.e.r = R;
+ if (range.e.c < C) range.e.c = C;
+ let cell = {
+ v: data[R][C],
+ };
+ if (cell.v == null) continue;
+ let cell_ref = XLSX.utils.encode_cell({
+ c: C,
+ r: R,
+ });
+
+ if (typeof cell.v === "number") cell.t = "n";
+ else if (typeof cell.v === "boolean") cell.t = "b";
+ else if (cell.v instanceof Date) {
+ cell.t = "n";
+ cell.z = XLSX.SSF._table[14];
+ cell.v = datenum(cell.v);
+ } else cell.t = "s";
+
+ ws[cell_ref] = cell;
+ }
+ }
+ if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
+ return ws;
+}
+
+function Workbook() {
+ if (!(this instanceof Workbook)) return new Workbook();
+ this.SheetNames = [];
+ this.Sheets = {};
+}
+
+function s2ab(s) {
+ let buf = new ArrayBuffer(s.length);
+ let view = new Uint8Array(buf);
+ for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
+ return buf;
+}
+
+export function export_table_to_excel(id) {
+ let theTable = document.getElementById(id);
+ let oo = generateArray(theTable);
+ let ranges = oo[1];
+
+ let data = oo[0];
+ let ws_name = "SheetJS";
+
+ let wb = new Workbook(),
+ ws = sheet_from_array_of_arrays(data);
+
+ ws["!merges"] = ranges;
+
+ wb.SheetNames.push(ws_name);
+ wb.Sheets[ws_name] = ws;
+
+ let wbout = XLSX.write(wb, {
+ bookType: "xlsx",
+ bookSST: false,
+ type: "binary",
+ });
+
+ saveAs(
+ new Blob([s2ab(wbout)], {
+ type: "application/octet-stream",
+ }),
+ "test.xlsx"
+ );
+}
+
+export function export_json_to_excel({
+ multiHeader = [],
+ header,
+ data,
+ filename,
+ merges = [],
+ autoWidth = true,
+ bookType = "xlsx",
+} = {}) {
+ filename = filename || "excel-list";
+ data = [...data];
+ data.unshift(header);
+
+ for (let i = multiHeader.length - 1; i > -1; i--) {
+ data.unshift(multiHeader[i]);
+ }
+
+ let ws_name = "SheetJS";
+ let wb = new Workbook(),
+ ws = sheet_from_array_of_arrays(data);
+
+ if (merges.length > 0) {
+ if (!ws["!merges"]) ws["!merges"] = [];
+ merges.forEach((item) => {
+ ws["!merges"].push(XLSX.utils.decode_range(item));
+ });
+ }
+
+ if (autoWidth) {
+ const colWidth = data.map((row) =>
+ row.map((val) => {
+ if (val == null) {
+ return {
+ wch: 10,
+ };
+ } else if (val.toString().charCodeAt(0) > 255) {
+ return {
+ wch: val.toString().length * 2,
+ };
+ } else {
+ return {
+ wch: val.toString().length,
+ };
+ }
+ })
+ );
+ let result = colWidth[0];
+ for (let i = 1; i < colWidth.length; i++) {
+ for (let j = 0; j < colWidth[i].length; j++) {
+ if (result[j]["wch"] < colWidth[i][j]["wch"]) {
+ result[j]["wch"] = colWidth[i][j]["wch"];
+ }
+ }
+ }
+ ws["!cols"] = result;
+ }
+
+ wb.SheetNames.push(ws_name);
+ wb.Sheets[ws_name] = ws;
+
+ let wbout = XLSX.write(wb, {
+ bookType: bookType,
+ bookSST: false,
+ type: "binary",
+ });
+ saveAs(
+ new Blob([s2ab(wbout)], {
+ type: "application/octet-stream",
+ }),
+ `${filename}.${bookType}`
+ );
+}
diff --git a/src/views/401.vue b/src/views/401.vue
new file mode 100644
index 0000000..67d074c
--- /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..35feb77
--- /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..8891e81
--- /dev/null
+++ b/src/views/index/index.vue
@@ -0,0 +1,819 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 访问量
+
+
+
+ 日均访问量:
+
+
+
+
+
+
+
+
+
+ 授权数
+
+
+
+ 总授权数:
+
+
+
+
+
+
+
+ 词云
+
+
+
+ 词云数量:
+
+
+
+
+
+
+ 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..628b939
--- /dev/null
+++ b/src/views/login/index.vue
@@ -0,0 +1,319 @@
+
+
+
+
+
+
+ 占位符
+
+
+
+
+ hello !
+
+ 欢迎来到{{ title }}!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+ 注册
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mall/goodsDetail/index.vue b/src/views/mall/goodsDetail/index.vue
new file mode 100644
index 0000000..6966480
--- /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..bb39f0f
--- /dev/null
+++ b/src/views/mall/goodsList/index.vue
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+ 推荐
+ 缺货
+
+
+
+
+
{{ 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..01e70aa
--- /dev/null
+++ b/src/views/mall/pay/components/Step1.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+ 请务必仔细填写并核对
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 下一步
+
+
+
+
+
diff --git a/src/views/mall/pay/components/Step2.vue b/src/views/mall/pay/components/Step2.vue
new file mode 100644
index 0000000..b716ccf
--- /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..e0d4366
--- /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..f322e12
--- /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..09a512c
--- /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..e4344ee
--- /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..5632237
--- /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..d74e569
--- /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..725ff80
--- /dev/null
+++ b/src/views/personnelManagement/roleManagement/index.vue
@@ -0,0 +1,160 @@
+
+
+
+ 演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将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..8afa766
--- /dev/null
+++ b/src/views/personnelManagement/userManagement/components/UserManagementEdit.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/personnelManagement/userManagement/index.vue b/src/views/personnelManagement/userManagement/index.vue
new file mode 100644
index 0000000..8dd6a54
--- /dev/null
+++ b/src/views/personnelManagement/userManagement/index.vue
@@ -0,0 +1,176 @@
+
+
+
+
+ 添加
+ 批量删除
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ item
+ }}
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/register/index.vue b/src/views/register/index.vue
new file mode 100644
index 0000000..cfc1994
--- /dev/null
+++ b/src/views/register/index.vue
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+ 占位符
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ phoneCode }}
+
+
+
+
+
+
+ 注册
+
+
+ 登录
+
+
+
+
+
+
+
+
+
diff --git a/src/views/test/index.vue b/src/views/test/index.vue
new file mode 100644
index 0000000..7faca44
--- /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..ea5cf04
--- /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..2031001
--- /dev/null
+++ b/src/views/vab/betterScroll/index.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
diff --git a/src/views/vab/card/index.vue b/src/views/vab/card/index.vue
new file mode 100644
index 0000000..9885417
--- /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..5e0f5b3
--- /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..c2ae1b8
--- /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..39083c0
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibitionBody.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ {{ 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..3fbf137
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibitionHeader.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
+
diff --git a/src/views/vab/codeGenerator/components/TableExhibitionQuery.vue b/src/views/vab/codeGenerator/components/TableExhibitionQuery.vue
new file mode 100644
index 0000000..0fa1f06
--- /dev/null
+++ b/src/views/vab/codeGenerator/components/TableExhibitionQuery.vue
@@ -0,0 +1,79 @@
+
+
+
+ 查看代码
+ 复制代码
+
+
+
+
+
+
+
+
+
+
+
+
+
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..b8cb9ea
--- /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..fe3a36e
--- /dev/null
+++ b/src/views/vab/echarts/index.vue
@@ -0,0 +1,655 @@
+
+
+
+
+
+ 柱状图
+
+
+
+
+
+
+
+ 环形图
+
+
+
+
+
+
+
+ 关系图
+
+
+
+
+
+
+
+
+ 中国地图
+
+
+
+
+
+
+
+ 世界地图
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/editor/index.vue b/src/views/vab/editor/index.vue
new file mode 100644
index 0000000..fe261e2
--- /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..f873b0a
--- /dev/null
+++ b/src/views/vab/element/index.vue
@@ -0,0 +1,253 @@
+
+
+
+
+ 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..1d04809
--- /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..fb50328
--- /dev/null
+++ b/src/views/vab/errorLog/index.vue
@@ -0,0 +1,28 @@
+
+
+ 这里会在顶部navbar上模拟一个控制台错误日志
+
+ 点击模拟一个chuzhixinjiayou的错误
+
+
+
+
+
+
diff --git a/src/views/vab/excel/exportExcel.vue b/src/views/vab/excel/exportExcel.vue
new file mode 100644
index 0000000..22047b2
--- /dev/null
+++ b/src/views/vab/excel/exportExcel.vue
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是
+
+
+ 否
+
+
+
+
+
+
+ 导出 Excel
+
+
+
+
+
+
+
+
+
+ {{ scope.$index + 1 }}
+
+
+
+
+ {{ scope.row.title }}
+
+
+
+
+ {{ scope.row.author }}
+
+
+
+
+ {{ scope.row.pageViews }}
+
+
+
+
+ {{ scope.row.datetime }}
+
+
+
+
+
+
+
diff --git a/src/views/vab/excel/exportMergeHeaderExcel.vue b/src/views/vab/excel/exportMergeHeaderExcel.vue
new file mode 100644
index 0000000..a10a0ca
--- /dev/null
+++ b/src/views/vab/excel/exportMergeHeaderExcel.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
diff --git a/src/views/vab/excel/exportSelectExcel.vue b/src/views/vab/excel/exportSelectExcel.vue
new file mode 100644
index 0000000..689163a
--- /dev/null
+++ b/src/views/vab/excel/exportSelectExcel.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+ 导出选中行
+
+
+
+
+
+
+
+
+
+
+ {{ scope.$index + 1 }}
+
+
+
+
+ {{ scope.row.title }}
+
+
+
+
+ {{ scope.row.author }}
+
+
+
+
+ {{ scope.row.pageViews }}
+
+
+
+
+ {{ scope.row.datetime }}
+
+
+
+
+
+
+
diff --git a/src/views/vab/excel/uploadExcel.vue b/src/views/vab/excel/uploadExcel.vue
new file mode 100644
index 0000000..752990a
--- /dev/null
+++ b/src/views/vab/excel/uploadExcel.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/form/index.vue b/src/views/vab/form/index.vue
new file mode 100644
index 0000000..fd39c68
--- /dev/null
+++ b/src/views/vab/form/index.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 立即创建
+
+ 重置
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/icon/colorfulIcon.vue b/src/views/vab/icon/colorfulIcon.vue
new file mode 100644
index 0000000..ab6306a
--- /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..5b3af6a
--- /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..e15fd52
--- /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..1670116
--- /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..277bbba
--- /dev/null
+++ b/src/views/vab/loading/index.vue
@@ -0,0 +1,69 @@
+
+
+ 传统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..04885c3
--- /dev/null
+++ b/src/views/vab/lodash/index.vue
@@ -0,0 +1,210 @@
+
+
+
+
+
+ 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..e53063f
--- /dev/null
+++ b/src/views/vab/magnifier/index.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+ 放大镜1
+
+
+
+
+
+ 放大镜2
+
+
+
+
+
+
+
+
diff --git a/src/views/vab/map/amap.vue b/src/views/vab/map/amap.vue
new file mode 100644
index 0000000..c3fd275
--- /dev/null
+++ b/src/views/vab/map/amap.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
diff --git a/src/views/vab/map/index.vue b/src/views/vab/map/index.vue
new file mode 100644
index 0000000..32f6a51
--- /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..c68671a
--- /dev/null
+++ b/src/views/vab/markdown/index.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
diff --git a/src/views/vab/markdown/js/markdown.js b/src/views/vab/markdown/js/markdown.js
new file mode 100644
index 0000000..4d467a8
--- /dev/null
+++ b/src/views/vab/markdown/js/markdown.js
@@ -0,0 +1,387 @@
+const md = `---
+id: options
+title: Options
+---
+
+Prettier ships with a handful of customizable format options, usable in both the CLI and API.
+
+## Print Width
+
+Specify the line length that the printer will wrap on.
+
+> **For readability we recommend against using more than 80 characters:**
+>
+> In code styleguides, maximum line length rules are often set to 100 or 120. However, when humans write code, they don't strive to reach the maximum number of columns on every line. Developers often use whitespace to break up long lines for readability. In practice, the average line length often ends up well below the maximum.
+>
+> Prettier, on the other hand, strives to fit the most code into every line. With the print width set to 120, prettier may produce overly compact, or otherwise undesirable code.
+>
+> See the [print width rationale](rationale.md#print-width) for more information.
+
+| Default | CLI Override | API Override |
+| ------- | --------------------- | ------------------- |
+| \`80\` | \`--print-width \` | \`printWidth: \` |
+
+(If you don't want line wrapping when formatting Markdown, you can set the [Prose Wrap](#prose-wrap) option to disable it.)
+
+## Tab Width
+
+Specify the number of spaces per indentation-level.
+
+| Default | CLI Override | API Override |
+| ------- | ------------------- | ----------------- |
+| \`2\` | \`--tab-width \` | \`tabWidth: \` |
+
+## Tabs
+
+Indent lines with tabs instead of spaces.
+
+| Default | CLI Override | API Override |
+| ------- | ------------ | ----------------- |
+| \`false\` | \`--use-tabs\` | \`useTabs: \` |
+
+(Tabs will be used for _indentation_ but Prettier uses spaces to _align_ things, such as in ternaries.)
+
+## Semicolons
+
+Print semicolons at the ends of statements.
+
+Valid options:
+
+- \`true\` - Add a semicolon at the end of every statement.
+- \`false\` - Only add semicolons at the beginning of lines that [may introduce ASI failures](rationale.md#semicolons).
+
+| Default | CLI Override | API Override |
+| ------- | ------------ | -------------- |
+| \`true\` | \`--no-semi\` | \`semi: \` |
+
+## Quotes
+
+Use single quotes instead of double quotes.
+
+Notes:
+
+- JSX quotes ignore this option – see [jsx-single-quote](#jsx-quotes).
+- If the number of quotes outweighs the other quote, the quote which is less used will be used to format the string - Example: \`"I'm double quoted"\` results in \`"I'm double quoted"\` and \`"This \\"example\\" is single quoted"\` results in \`'This "example" is single quoted'\`.
+
+See the [strings rationale](rationale.md#strings) for more information.
+
+| Default | CLI Override | API Override |
+| ------- | ---------------- | --------------------- |
+| \`false\` | \`--single-quote\` | \`singleQuote: \` |
+
+## Quote Props
+
+Change when properties in objects are quoted.
+
+Valid options:
+
+- \`"as-needed"\` - Only add quotes around object properties where required.
+- \`"consistent"\` - If at least one property in an object requires quotes, quote all properties.
+- \`"preserve"\` - Respect the input use of quotes in object properties.
+
+| Default | CLI Override | API Override |
+| ------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
+| \`"as-needed"\` | --quote-props
| quoteProps: ""
|
+
+## JSX Quotes
+
+Use single quotes instead of double quotes in JSX.
+
+| Default | CLI Override | API Override |
+| ------- | -------------------- | ------------------------ |
+| \`false\` | \`--jsx-single-quote\` | \`jsxSingleQuote: \` |
+
+## Trailing Commas
+
+_Default value changed from \`none\` to \`es5\` in v2.0.0_
+
+Print trailing commas wherever possible when multi-line. (A single-line array, for example, never gets trailing commas.)
+
+Valid options:
+
+- \`"es5"\` - Trailing commas where valid in ES5 (objects, arrays, etc.)
+- \`"none"\` - No trailing commas.
+- \`"all"\` - Trailing commas wherever possible (including function arguments). This requires node 8 or a [transform](https://babeljs.io/docs/plugins/syntax-trailing-function-commas/).
+
+| Default | CLI Override | API Override |
+| ------- | ------------------------------------------------------ | ------------------------------------------------------ |
+| \`"es5"\` | --trailing-comma
| trailingComma: ""
|
+
+## Bracket Spacing
+
+Print spaces between brackets in object literals.
+
+Valid options:
+
+- \`true\` - Example: \`{ foo: bar }\`.
+- \`false\` - Example: \`{foo: bar}\`.
+
+| Default | CLI Override | API Override |
+| ------- | ---------------------- | ------------------------ |
+| \`true\` | \`--no-bracket-spacing\` | \`bracketSpacing: \` |
+
+## JSX Brackets
+
+Put the \`>\` of a multi-line JSX element at the end of the last line instead of being alone on the next line (does not apply to self closing elements).
+
+Valid options:
+
+- \`true\` - Example:
+
+
+\`\`\`jsx
+
+ Click Here
+
+\`\`\`
+
+- \`false\` - Example:
+
+
+\`\`\`jsx
+
+ Click Here
+
+\`\`\`
+
+| Default | CLI Override | API Override |
+| ------- | ------------------------- | ---------------------------- |
+| \`false\` | \`--jsx-bracket-same-line\` | \`jsxBracketSameLine: \` |
+
+## Arrow Function Parentheses
+
+_First available in v1.9.0, default value changed from \`avoid\` to \`always\` in v2.0.0_
+
+Include parentheses around a sole arrow function parameter.
+
+Valid options:
+
+- \`"always"\` - Always include parens. Example: \`(x) => x\`
+- \`"avoid"\` - Omit parens when possible. Example: \`x => x\`
+
+| Default | CLI Override | API Override |
+| ---------- | ----------------------------------------------- | ----------------------------------------------- |
+| \`"always"\` | --arrow-parens
| arrowParens: ""
|
+
+At first glance, avoiding parentheses may look like a better choice because of less visual noise.
+However, when Prettier removes parentheses, it becomes harder to add type annotations, extra arguments or default values as well as making other changes.
+Consistent use of parentheses provides a better developer experience when editing real codebases, which justifies the default value for the option.
+
+## Range
+
+Format only a segment of a file.
+
+These two options can be used to format code starting and ending at a given character offset (inclusive and exclusive, respectively). The range will extend:
+
+- Backwards to the start of the first line containing the selected statement.
+- Forwards to the end of the selected statement.
+
+These options cannot be used with \`cursorOffset\`.
+
+| Default | CLI Override | API Override |
+| ---------- | --------------------- | ------------------- |
+| \`0\` | \`--range-start \` | \`rangeStart: \` |
+| \`Infinity\` | \`--range-end \` | \`rangeEnd: \` |
+
+## Parser
+
+Specify which parser to use.
+
+Prettier automatically infers the parser from the input file path, so you shouldn't have to change this setting.
+
+Both the \`babel\` and \`flow\` parsers support the same set of JavaScript features (including Flow type annotations). They might differ in some edge cases, so if you run into one of those you can try \`flow\` instead of \`babel\`. Almost the same applies to \`typescript\` and \`babel-ts\`. \`babel-ts\` might support JavaScript features (proposals) not yet supported by TypeScript, but it's less permissive when it comes to invalid code and less battle-tested than the \`typescript\` parser.
+
+Valid options:
+
+- \`"babel"\` (via [@babel/parser](https://github.com/babel/babel/tree/master/packages/babel-parser)) _Named \`"babylon"\` until v1.16.0_
+- \`"babel-flow"\` (same as \`"babel"\` but enables Flow parsing explicitly to avoid ambiguity) _First available in v1.16.0_
+- \`"babel-ts"\` (similar to \`"typescript"\` but uses Babel and its TypeScript plugin) _First available in v2.0.0_
+- \`"flow"\` (via [flow-parser](https://github.com/facebook/flow/tree/master/src/parser))
+- \`"typescript"\` (via [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint)) _First available in v1.4.0_
+- \`"css"\` (via [postcss-scss](https://github.com/postcss/postcss-scss) and [postcss-less](https://github.com/shellscape/postcss-less), autodetects which to use) _First available in v1.7.1_
+- \`"scss"\` (same parsers as \`"css"\`, prefers postcss-scss) _First available in v1.7.1_
+- \`"less"\` (same parsers as \`"css"\`, prefers postcss-less) _First available in v1.7.1_
+- \`"json"\` (via [@babel/parser parseExpression](https://babeljs.io/docs/en/next/babel-parser.html#babelparserparseexpressioncode-options)) _First available in v1.5.0_
+- \`"json5"\` (same parser as \`"json"\`, but outputs as [json5](https://json5.org/)) _First available in v1.13.0_
+- \`"json-stringify"\` (same parser as \`"json"\`, but outputs like \`JSON.stringify\`) _First available in v1.13.0_
+- \`"graphql"\` (via [graphql/language](https://github.com/graphql/graphql-js/tree/master/src/language)) _First available in v1.5.0_
+- \`"markdown"\` (via [remark-parse](https://github.com/wooorm/remark/tree/master/packages/remark-parse)) _First available in v1.8.0_
+- \`"mdx"\` (via [remark-parse](https://github.com/wooorm/remark/tree/master/packages/remark-parse) and [@mdx-js/mdx](https://github.com/mdx-js/mdx/tree/master/packages/mdx)) _First available in v1.15.0_
+- \`"html"\` (via [angular-html-parser](https://github.com/ikatyang/angular-html-parser/tree/master/packages/angular-html-parser)) _First available in 1.15.0_
+- \`"vue"\` (same parser as \`"html"\`, but also formats vue-specific syntax) _First available in 1.10.0_
+- \`"angular"\` (same parser as \`"html"\`, but also formats angular-specific syntax via [angular-estree-parser](https://github.com/ikatyang/angular-estree-parser)) _First available in 1.15.0_
+- \`"lwc"\` (same parser as \`"html"\`, but also formats LWC-specific syntax for unquoted template attributes) _First available in 1.17.0_
+- \`"yaml"\` (via [yaml](https://github.com/eemeli/yaml) and [yaml-unist-parser](https://github.com/ikatyang/yaml-unist-parser)) _First available in 1.14.0_
+
+[Custom parsers](api.md#custom-parser-api) are also supported. _First available in v1.5.0_
+
+| Default | CLI Override | API Override |
+| ------- | ----------------------------------------------- | ---------------------------------------------------------- |
+| None | \`--parser \` \`--parser ./my-parser\` | \`parser: ""\` \`parser: require("./my-parser")\` |
+
+Note: the default value was \`"babylon"\` until v1.13.0.
+
+
+
+## File Path
+
+Specify the file name to use to infer which parser to use.
+
+For example, the following will use the CSS parser:
+
+\`\`\`bash
+cat foo | prettier --stdin-filepath foo.css
+\`\`\`
+
+| Default | CLI Override | API Override |
+| ------- | --------------------------- | ---------------------- |
+| None | \`--stdin-filepath \` | \`filepath: ""\` |
+
+## Require pragma
+
+_First available in v1.7.0_
+
+Prettier can restrict itself to only format files that contain a special comment, called a pragma, at the top of the file. This is very useful when gradually transitioning large, unformatted codebases to prettier.
+
+For example, a file with the following as its first comment will be formatted when \`--require-pragma\` is supplied:
+
+\`\`\`js
+/**
+ * @prettier
+ */
+\`\`\`
+
+or
+
+\`\`\`js
+/**
+ * @format
+ */
+\`\`\`
+
+| Default | CLI Override | API Override |
+| ------- | ------------------ | ----------------------- |
+| \`false\` | \`--require-pragma\` | \`requirePragma: \` |
+
+## Insert Pragma
+
+_First available in v1.8.0_
+
+Prettier can insert a special @format marker at the top of files specifying that the file has been formatted with prettier. This works well when used in tandem with the \`--require-pragma\` option. If there is already a docblock at the top of the file then this option will add a newline to it with the @format marker.
+
+| Default | CLI Override | API Override |
+| ------- | ----------------- | ---------------------- |
+| \`false\` | \`--insert-pragma\` | \`insertPragma: \` |
+
+## Prose Wrap
+
+_First available in v1.8.2_
+
+By default, Prettier will wrap markdown text as-is since some services use a linebreak-sensitive renderer, e.g. GitHub comment and BitBucket. In some cases you may want to rely on editor/viewer soft wrapping instead, so this option allows you to opt out with \`"never"\`.
+
+Valid options:
+
+- \`"always"\` - Wrap prose if it exceeds the print width.
+- \`"never"\` - Do not wrap prose.
+- \`"preserve"\` - Wrap prose as-is. _First available in v1.9.0_
+
+| Default | CLI Override | API Override |
+| ------------ | ----------------------------------------------------------- | ----------------------------------------------------------- |
+| \`"preserve"\` | --prose-wrap
| proseWrap: ""
|
+
+## HTML Whitespace Sensitivity
+
+_First available in v1.15.0_
+
+Specify the global whitespace sensitivity for HTML files, see [whitespace-sensitive formatting] for more info.
+
+[whitespace-sensitive formatting]: https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting
+
+Valid options:
+
+- \`"css"\` - Respect the default value of CSS \`display\` property.
+- \`"strict"\` - Whitespaces are considered sensitive.
+- \`"ignore"\` - Whitespaces are considered insensitive.
+
+| Default | CLI Override | API Override |
+| ------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
+| \`"css"\` | --html-whitespace-sensitivity
| htmlWhitespaceSensitivity: ""
|
+
+## Vue files script and style tags indentation
+
+_First available in v1.19.0_
+
+Whether or not to indent the code inside \`
diff --git a/src/views/vab/more/index.vue b/src/views/vab/more/index.vue
new file mode 100644
index 0000000..a5e7149
--- /dev/null
+++ b/src/views/vab/more/index.vue
@@ -0,0 +1,115 @@
+
+
+
+ 看到这里,你心动了吗?如果你心动了那就加入我们的qq群吧(972435319),谢谢你愿意尊重作者的心血,希望我们每个人都变得优秀,如果你愿意跟随作者一起学习技术,作者QQ(1204505056白嫖党勿扰)
+
+
+
+
+
+ 开源版本
+ 永久免费 个人/商业使用
+
+
+
+
+ 永久开源免费
+ 保留控制台以及代码中的作者信息可免费商用
+
+ 开源地址
+ 支持白嫖,也请给个star
+
+
+ 提供讨论群专属文档,QQ群 972435319
+
+
+
+
+
+
+
+
+
+ VIP群
+ ¥100
+
+
+
+ 支持以上所有特权
+
+ 提供vip群专属文档及视频教程,可快速入手框架,包含打包优化,公共布局zx-layouts
+ npm包本地化教程等
+
+ QQ咨询 1204505056
+
+
+
+
+
+
+
+ 商业用途 完全自定义版权
+ ¥299
+
+
+
+ 支持以上所有特权
+
+ 可随意变更版权,但仅限自己团队使用,一旦发现恶意传播,二次售卖,不再提供更新支持
+
+ 永久更新
+ 优先问题解答
+ 提供低价外包合作机会
+
+
+
+
+
+
+
+
+
+
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..35c8eef
--- /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..e35d3f3
--- /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..d0d7379
--- /dev/null
+++ b/src/views/vab/permissions/index.vue
@@ -0,0 +1,165 @@
+
+
+
+ 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..ab2f81c
--- /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..0c3593e
--- /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..f3a013b
--- /dev/null
+++ b/src/views/vab/smallComponents/index.vue
@@ -0,0 +1,109 @@
+
+
+
+
+ 小组件
+
+
+
+
+ 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..589b557
--- /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..a3b5243
--- /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..051c0a1
--- /dev/null
+++ b/src/views/vab/table/index.vue
@@ -0,0 +1,265 @@
+
+
+
+
+ 添加
+
+ 删除
+
+ 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..e6aa360
--- /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..ea78822
--- /dev/null
+++ b/src/views/vab/tree/index.vue
@@ -0,0 +1,471 @@
+
+
+
+
+
diff --git a/src/views/vab/upload/index.vue b/src/views/vab/upload/index.vue
new file mode 100644
index 0000000..5d1c78e
--- /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..43432c8
--- /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..e0650b0
--- /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..0561889
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,208 @@
+const path = require("path");
+const {
+ publicPath,
+ assetsDir,
+ outputDir,
+ lintOnSave,
+ transpileDependencies,
+ title,
+ abbreviation,
+ devPort,
+ providePlugin,
+ build7z,
+} = require("./src/config/settings");
+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 = new dayjs().format("YYYY_M_D");
+const time = new 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";
+process.env.VUE_APP_UPDATE_TIME = time;
+process.env.VUE_APP_VERSION = version;
+function resolve(dir) {
+ return path.join(__dirname, dir);
+}
+
+function mockServer() {
+ if (process.env.NODE_ENV === "development") {
+ const mockServer = require("./mock/mockServer.js");
+ return mockServer;
+ } 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"),
+ "^": resolve("src/components"),
+ },
+ },
+ plugins: [
+ new Webpack.ProvidePlugin(providePlugin),
+ new WebpackBar({
+ name: `\u0076\u0075\u0065\u002d\u0061\u0064\u006d\u0069\u006e\u002d\u0062\u0065\u0061\u0075\u0074\u0069\u0066\u0075\u006c`,
+ }),
+ ],
+ };
+ },
+ 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("cheap-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, [
+ ` \u57fa\u4e8e\u0076\u0075\u0065\u002d\u0061\u0064\u006d\u0069\u006e\u002d\u0062\u0065\u0061\u0075\u0074\u0069\u0066\u0075\u006c\u6784\u5efa \n \u0063\u006f\u0070\u0079\u0072\u0069\u0067\u0068\u0074\u003a\u0020\u0063\u0068\u0075\u007a\u0068\u0069\u0078\u0069\u006e\u0020\u0031\u0032\u0030\u0034\u0035\u0030\u0035\u0030\u0035\u0036\u0040\u0071\u0071\u002e\u0063\u006f\u006d \n \u0074\u0069\u006d\u0065\u003a ${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;
+ },
+ },
+ },
+ },
+};