From 03bc3d1259a3d2fef0ec035089096e0804be043b Mon Sep 17 00:00:00 2001
From: wen <1515>
Date: Sat, 1 Oct 2022 12:14:37 +0800
Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E7=AE=A1=E7=90=86=E7=B3=BB?=
=?UTF-8?q?=E7=BB=9F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.editorconfig | 14 +
.env.development | 5 +
.env.production | 6 +
.env.staging | 8 +
.eslintignore | 4 +
.eslintrc.js | 198 ++++++++++++++
.gitignore | 16 ++
.travis.yml | 5 +
LICENSE | 21 ++
README-zh.md | 111 ++++++++
README.md | 99 +++++++
babel.config.js | 14 +
build/index.js | 35 +++
jest.config.js | 24 ++
jsconfig.json | 9 +
mock/index.js | 57 ++++
mock/mock-server.js | 81 ++++++
mock/table.js | 29 +++
mock/user.js | 84 ++++++
mock/utils.js | 25 ++
package.json | 62 +++++
postcss.config.js | 8 +
public/index.html | 17 ++
public/jialuoma.ico | Bin 0 -> 8849 bytes
public/jialuoma2.ico | Bin 0 -> 26050 bytes
src/App.vue | 11 +
src/api/table.js | 9 +
src/api/user.js | 24 ++
src/assets/404_images/404.png | Bin 0 -> 98071 bytes
src/assets/404_images/404_cloud.png | Bin 0 -> 4766 bytes
src/components/Breadcrumb/index.vue | 79 ++++++
src/components/Hamburger/index.vue | 44 ++++
src/components/SvgIcon/index.vue | 62 +++++
src/icons/index.js | 9 +
src/icons/svg/dashboard.svg | 1 +
src/icons/svg/example.svg | 1 +
src/icons/svg/eye-open.svg | 1 +
src/icons/svg/eye.svg | 1 +
src/icons/svg/form.svg | 1 +
src/icons/svg/link.svg | 1 +
src/icons/svg/nested.svg | 1 +
src/icons/svg/password.svg | 1 +
src/icons/svg/table.svg | 1 +
src/icons/svg/tree.svg | 1 +
src/icons/svg/user.svg | 1 +
src/icons/svgo.yml | 22 ++
src/layout/components/AppMain.vue | 40 +++
src/layout/components/Navbar.vue | 133 ++++++++++
src/layout/components/Sidebar/FixiOSBug.js | 26 ++
src/layout/components/Sidebar/Item.vue | 41 +++
src/layout/components/Sidebar/Link.vue | 43 +++
src/layout/components/Sidebar/Logo.vue | 82 ++++++
src/layout/components/Sidebar/SidebarItem.vue | 95 +++++++
src/layout/components/Sidebar/index.vue | 56 ++++
src/layout/components/index.js | 3 +
src/layout/index.vue | 93 +++++++
src/layout/mixin/ResizeHandler.js | 45 ++++
src/main.js | 43 +++
src/permission.js | 64 +++++
src/router/index.js | 222 ++++++++++++++++
src/settings.js | 16 ++
src/store/getters.js | 8 +
src/store/index.js | 19 ++
src/store/modules/app.js | 48 ++++
src/store/modules/settings.js | 32 +++
src/store/modules/user.js | 97 +++++++
src/styles/element-ui.scss | 49 ++++
src/styles/index.scss | 65 +++++
src/styles/mixin.scss | 28 ++
src/styles/sidebar.scss | 226 ++++++++++++++++
src/styles/transition.scss | 48 ++++
src/styles/variables.scss | 25 ++
src/utils/auth.js | 15 ++
src/utils/get-page-title.js | 10 +
src/utils/index.js | 117 +++++++++
src/utils/request.js | 85 ++++++
src/utils/validate.js | 23 ++
src/views/404.vue | 228 ++++++++++++++++
src/views/dashboard/index.vue | 28 ++
src/views/form/index.vue | 87 +++++++
src/views/login/index.vue | 244 ++++++++++++++++++
src/views/nested/menu1/index.vue | 7 +
src/views/nested/menu1/menu1-1/index.vue | 7 +
src/views/nested/menu1/menu1-2/index.vue | 7 +
.../nested/menu1/menu1-2/menu1-2-1/index.vue | 5 +
.../nested/menu1/menu1-2/menu1-2-2/index.vue | 5 +
src/views/nested/menu1/menu1-3/index.vue | 5 +
src/views/nested/menu2/index.vue | 5 +
src/views/systme/changepass.vue | 101 ++++++++
src/views/systme/userrelated.vue | 34 +++
src/views/table/index.vue | 79 ++++++
src/views/tree/index.vue | 78 ++++++
src/views/usermanage/index.vue | 79 ++++++
tests/unit/.eslintrc.js | 5 +
tests/unit/components/Breadcrumb.spec.js | 98 +++++++
tests/unit/components/Hamburger.spec.js | 18 ++
tests/unit/components/SvgIcon.spec.js | 22 ++
tests/unit/utils/formatTime.spec.js | 30 +++
tests/unit/utils/param2Obj.spec.js | 14 +
tests/unit/utils/parseTime.spec.js | 35 +++
tests/unit/utils/validate.spec.js | 17 ++
vue.config.js | 125 +++++++++
102 files changed, 4463 insertions(+)
create mode 100644 .editorconfig
create mode 100644 .env.development
create mode 100644 .env.production
create mode 100644 .env.staging
create mode 100644 .eslintignore
create mode 100644 .eslintrc.js
create mode 100644 .gitignore
create mode 100644 .travis.yml
create mode 100644 LICENSE
create mode 100644 README-zh.md
create mode 100644 README.md
create mode 100644 babel.config.js
create mode 100644 build/index.js
create mode 100644 jest.config.js
create mode 100644 jsconfig.json
create mode 100644 mock/index.js
create mode 100644 mock/mock-server.js
create mode 100644 mock/table.js
create mode 100644 mock/user.js
create mode 100644 mock/utils.js
create mode 100644 package.json
create mode 100644 postcss.config.js
create mode 100644 public/index.html
create mode 100644 public/jialuoma.ico
create mode 100644 public/jialuoma2.ico
create mode 100644 src/App.vue
create mode 100644 src/api/table.js
create mode 100644 src/api/user.js
create mode 100644 src/assets/404_images/404.png
create mode 100644 src/assets/404_images/404_cloud.png
create mode 100644 src/components/Breadcrumb/index.vue
create mode 100644 src/components/Hamburger/index.vue
create mode 100644 src/components/SvgIcon/index.vue
create mode 100644 src/icons/index.js
create mode 100644 src/icons/svg/dashboard.svg
create mode 100644 src/icons/svg/example.svg
create mode 100644 src/icons/svg/eye-open.svg
create mode 100644 src/icons/svg/eye.svg
create mode 100644 src/icons/svg/form.svg
create mode 100644 src/icons/svg/link.svg
create mode 100644 src/icons/svg/nested.svg
create mode 100644 src/icons/svg/password.svg
create mode 100644 src/icons/svg/table.svg
create mode 100644 src/icons/svg/tree.svg
create mode 100644 src/icons/svg/user.svg
create mode 100644 src/icons/svgo.yml
create mode 100644 src/layout/components/AppMain.vue
create mode 100644 src/layout/components/Navbar.vue
create mode 100644 src/layout/components/Sidebar/FixiOSBug.js
create mode 100644 src/layout/components/Sidebar/Item.vue
create mode 100644 src/layout/components/Sidebar/Link.vue
create mode 100644 src/layout/components/Sidebar/Logo.vue
create mode 100644 src/layout/components/Sidebar/SidebarItem.vue
create mode 100644 src/layout/components/Sidebar/index.vue
create mode 100644 src/layout/components/index.js
create mode 100644 src/layout/index.vue
create mode 100644 src/layout/mixin/ResizeHandler.js
create mode 100644 src/main.js
create mode 100644 src/permission.js
create mode 100644 src/router/index.js
create mode 100644 src/settings.js
create mode 100644 src/store/getters.js
create mode 100644 src/store/index.js
create mode 100644 src/store/modules/app.js
create mode 100644 src/store/modules/settings.js
create mode 100644 src/store/modules/user.js
create mode 100644 src/styles/element-ui.scss
create mode 100644 src/styles/index.scss
create mode 100644 src/styles/mixin.scss
create mode 100644 src/styles/sidebar.scss
create mode 100644 src/styles/transition.scss
create mode 100644 src/styles/variables.scss
create mode 100644 src/utils/auth.js
create mode 100644 src/utils/get-page-title.js
create mode 100644 src/utils/index.js
create mode 100644 src/utils/request.js
create mode 100644 src/utils/validate.js
create mode 100644 src/views/404.vue
create mode 100644 src/views/dashboard/index.vue
create mode 100644 src/views/form/index.vue
create mode 100644 src/views/login/index.vue
create mode 100644 src/views/nested/menu1/index.vue
create mode 100644 src/views/nested/menu1/menu1-1/index.vue
create mode 100644 src/views/nested/menu1/menu1-2/index.vue
create mode 100644 src/views/nested/menu1/menu1-2/menu1-2-1/index.vue
create mode 100644 src/views/nested/menu1/menu1-2/menu1-2-2/index.vue
create mode 100644 src/views/nested/menu1/menu1-3/index.vue
create mode 100644 src/views/nested/menu2/index.vue
create mode 100644 src/views/systme/changepass.vue
create mode 100644 src/views/systme/userrelated.vue
create mode 100644 src/views/table/index.vue
create mode 100644 src/views/tree/index.vue
create mode 100644 src/views/usermanage/index.vue
create mode 100644 tests/unit/.eslintrc.js
create mode 100644 tests/unit/components/Breadcrumb.spec.js
create mode 100644 tests/unit/components/Hamburger.spec.js
create mode 100644 tests/unit/components/SvgIcon.spec.js
create mode 100644 tests/unit/utils/formatTime.spec.js
create mode 100644 tests/unit/utils/param2Obj.spec.js
create mode 100644 tests/unit/utils/parseTime.spec.js
create mode 100644 tests/unit/utils/validate.spec.js
create mode 100644 vue.config.js
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..ea6e20f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,14 @@
+# http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..de583d0
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,5 @@
+# just a flag
+ENV = 'development'
+
+# base api
+VUE_APP_BASE_API = '/dev-api'
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..80c8103
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,6 @@
+# just a flag
+ENV = 'production'
+
+# base api
+VUE_APP_BASE_API = '/prod-api'
+
diff --git a/.env.staging b/.env.staging
new file mode 100644
index 0000000..a8793a0
--- /dev/null
+++ b/.env.staging
@@ -0,0 +1,8 @@
+NODE_ENV = production
+
+# just a flag
+ENV = 'staging'
+
+# base api
+VUE_APP_BASE_API = '/stage-api'
+
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..e6529fc
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,4 @@
+build/*.js
+src/assets
+public
+dist
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..c977505
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,198 @@
+module.exports = {
+ root: true,
+ parserOptions: {
+ parser: 'babel-eslint',
+ sourceType: 'module'
+ },
+ env: {
+ browser: true,
+ node: true,
+ es6: true,
+ },
+ extends: ['plugin:vue/recommended', 'eslint:recommended'],
+
+ // add your custom rules here
+ //it is base on https://github.com/vuejs/eslint-config-vue
+ rules: {
+ "vue/max-attributes-per-line": [2, {
+ "singleline": 10,
+ "multiline": {
+ "max": 1,
+ "allowFirstLine": false
+ }
+ }],
+ "vue/singleline-html-element-content-newline": "off",
+ "vue/multiline-html-element-content-newline":"off",
+ "vue/name-property-casing": ["error", "PascalCase"],
+ "vue/no-v-html": "off",
+ 'accessor-pairs': 2,
+ 'arrow-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'block-spacing': [2, 'always'],
+ 'brace-style': [2, '1tbs', {
+ 'allowSingleLine': true
+ }],
+ 'camelcase': [0, {
+ 'properties': 'always'
+ }],
+ 'comma-dangle': [2, 'never'],
+ 'comma-spacing': [2, {
+ 'before': false,
+ 'after': true
+ }],
+ 'comma-style': [2, 'last'],
+ 'constructor-super': 2,
+ 'curly': [2, 'multi-line'],
+ 'dot-location': [2, 'property'],
+ 'eol-last': 2,
+ 'eqeqeq': ["error", "always", {"null": "ignore"}],
+ 'generator-star-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'handle-callback-err': [2, '^(err|error)$'],
+ 'indent': [2, 2, {
+ 'SwitchCase': 1
+ }],
+ 'jsx-quotes': [2, 'prefer-single'],
+ 'key-spacing': [2, {
+ 'beforeColon': false,
+ 'afterColon': true
+ }],
+ 'keyword-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'new-cap': [2, {
+ 'newIsCap': true,
+ 'capIsNew': false
+ }],
+ 'new-parens': 2,
+ 'no-array-constructor': 2,
+ 'no-caller': 2,
+ 'no-console': 'off',
+ 'no-class-assign': 2,
+ 'no-cond-assign': 2,
+ 'no-const-assign': 2,
+ 'no-control-regex': 0,
+ 'no-delete-var': 2,
+ 'no-dupe-args': 2,
+ 'no-dupe-class-members': 2,
+ 'no-dupe-keys': 2,
+ 'no-duplicate-case': 2,
+ 'no-empty-character-class': 2,
+ 'no-empty-pattern': 2,
+ 'no-eval': 2,
+ 'no-ex-assign': 2,
+ 'no-extend-native': 2,
+ 'no-extra-bind': 2,
+ 'no-extra-boolean-cast': 2,
+ 'no-extra-parens': [2, 'functions'],
+ 'no-fallthrough': 2,
+ 'no-floating-decimal': 2,
+ 'no-func-assign': 2,
+ 'no-implied-eval': 2,
+ 'no-inner-declarations': [2, 'functions'],
+ 'no-invalid-regexp': 2,
+ 'no-irregular-whitespace': 2,
+ 'no-iterator': 2,
+ 'no-label-var': 2,
+ 'no-labels': [2, {
+ 'allowLoop': false,
+ 'allowSwitch': false
+ }],
+ 'no-lone-blocks': 2,
+ 'no-mixed-spaces-and-tabs': 2,
+ 'no-multi-spaces': 2,
+ 'no-multi-str': 2,
+ 'no-multiple-empty-lines': [2, {
+ 'max': 1
+ }],
+ 'no-native-reassign': 2,
+ 'no-negated-in-lhs': 2,
+ 'no-new-object': 2,
+ 'no-new-require': 2,
+ 'no-new-symbol': 2,
+ 'no-new-wrappers': 2,
+ 'no-obj-calls': 2,
+ 'no-octal': 2,
+ 'no-octal-escape': 2,
+ 'no-path-concat': 2,
+ 'no-proto': 2,
+ 'no-redeclare': 2,
+ 'no-regex-spaces': 2,
+ 'no-return-assign': [2, 'except-parens'],
+ 'no-self-assign': 2,
+ 'no-self-compare': 2,
+ 'no-sequences': 2,
+ 'no-shadow-restricted-names': 2,
+ 'no-spaced-func': 2,
+ 'no-sparse-arrays': 2,
+ 'no-this-before-super': 2,
+ 'no-throw-literal': 2,
+ 'no-trailing-spaces': 2,
+ 'no-undef': 2,
+ 'no-undef-init': 2,
+ 'no-unexpected-multiline': 2,
+ 'no-unmodified-loop-condition': 2,
+ 'no-unneeded-ternary': [2, {
+ 'defaultAssignment': false
+ }],
+ 'no-unreachable': 2,
+ 'no-unsafe-finally': 2,
+ 'no-unused-vars': [2, {
+ 'vars': 'all',
+ 'args': 'none'
+ }],
+ 'no-useless-call': 2,
+ 'no-useless-computed-key': 2,
+ 'no-useless-constructor': 2,
+ 'no-useless-escape': 0,
+ 'no-whitespace-before-property': 2,
+ 'no-with': 2,
+ 'one-var': [2, {
+ 'initialized': 'never'
+ }],
+ 'operator-linebreak': [2, 'after', {
+ 'overrides': {
+ '?': 'before',
+ ':': 'before'
+ }
+ }],
+ 'padded-blocks': [2, 'never'],
+ 'quotes': [2, 'single', {
+ 'avoidEscape': true,
+ 'allowTemplateLiterals': true
+ }],
+ 'semi': [2, 'never'],
+ 'semi-spacing': [2, {
+ 'before': false,
+ 'after': true
+ }],
+ 'space-before-blocks': [2, 'always'],
+ 'space-before-function-paren': [2, 'never'],
+ 'space-in-parens': [2, 'never'],
+ 'space-infix-ops': 2,
+ 'space-unary-ops': [2, {
+ 'words': true,
+ 'nonwords': false
+ }],
+ 'spaced-comment': [2, 'always', {
+ 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
+ }],
+ 'template-curly-spacing': [2, 'never'],
+ 'use-isnan': 2,
+ 'valid-typeof': 2,
+ 'wrap-iife': [2, 'any'],
+ 'yield-star-spacing': [2, 'both'],
+ 'yoda': [2, 'never'],
+ 'prefer-const': 2,
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+ 'object-curly-spacing': [2, 'always', {
+ objectsInObjects: false
+ }],
+ 'array-bracket-spacing': [2, 'never']
+ }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ad28d2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+.DS_Store
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+tests/**/coverage/
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f4be7a0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js: 10
+script: npm run test
+notifications:
+ email: false
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6151575
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-present PanJiaChen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README-zh.md b/README-zh.md
new file mode 100644
index 0000000..1beec9b
--- /dev/null
+++ b/README-zh.md
@@ -0,0 +1,111 @@
+# vue-admin-template
+
+> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。
+
+[线上地址](http://panjiachen.github.io/vue-admin-template)
+
+[国内访问](https://panjiachen.gitee.io/vue-admin-template)
+
+目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`。
+
+
+ SPONSORED BY
+
+
+
+
+
+
+
+## Extra
+
+如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+
+## 相关项目
+
+- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
+
+- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+
+- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
+
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
+
+- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
+- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
+- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
+- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
+- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
+
+## Build Setup
+
+```bash
+# 克隆项目
+git clone https://github.com/PanJiaChen/vue-admin-template.git
+
+# 进入项目目录
+cd vue-admin-template
+
+# 安装依赖
+npm install
+
+# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
+npm install --registry=https://registry.npm.taobao.org
+
+# 启动服务
+npm run dev
+```
+
+浏览器访问 [http://localhost:9528](http://localhost:9528)
+
+## 发布
+
+```bash
+# 构建测试环境
+npm run build:stage
+
+# 构建生产环境
+npm run build:prod
+```
+
+## 其它
+
+```bash
+# 预览发布环境效果
+npm run preview
+
+# 预览发布环境效果 + 静态资源分析
+npm run preview -- --report
+
+# 代码格式检查
+npm run lint
+
+# 代码格式检查并自动修复
+npm run lint -- --fix
+```
+
+更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
+
+## 购买贴纸
+
+你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。
+
+## Demo
+
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [](http://godban.github.io/browsers-support-badges/)IE / Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
+
+Copyright (c) 2017-present PanJiaChen
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fa54b78
--- /dev/null
+++ b/README.md
@@ -0,0 +1,99 @@
+# vue-admin-template
+
+English | [简体中文](./README-zh.md)
+
+> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
+
+**Live demo:** http://panjiachen.github.io/vue-admin-template
+
+
+**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
+
+
+ SPONSORED BY
+
+
+
+
+
+
+
+## Build Setup
+
+```bash
+# clone the project
+git clone https://github.com/PanJiaChen/vue-admin-template.git
+
+# enter the project directory
+cd vue-admin-template
+
+# install dependency
+npm install
+
+# develop
+npm run dev
+```
+
+This will automatically open http://localhost:9528
+
+## Build
+
+```bash
+# build for test environment
+npm run build:stage
+
+# build for production environment
+npm run build:prod
+```
+
+## Advanced
+
+```bash
+# preview the release environment effect
+npm run preview
+
+# preview the release environment effect + static resource analysis
+npm run preview -- --report
+
+# code format check
+npm run lint
+
+# code format check and auto fix
+npm run lint -- --fix
+```
+
+Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
+
+## Demo
+
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
+
+## Extra
+
+If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+
+For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
+
+## Related Project
+
+- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
+
+- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+
+- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
+
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [](http://godban.github.io/browsers-support-badges/)IE / Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
+
+Copyright (c) 2017-present PanJiaChen
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..fb82b27
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,14 @@
+module.exports = {
+ presets: [
+ // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
+ '@vue/cli-plugin-babel/preset'
+ ],
+ 'env': {
+ 'development': {
+ // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
+ // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
+ // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
+ 'plugins': ['dynamic-import-node']
+ }
+ }
+}
diff --git a/build/index.js b/build/index.js
new file mode 100644
index 0000000..0c57de2
--- /dev/null
+++ b/build/index.js
@@ -0,0 +1,35 @@
+const { run } = require('runjs')
+const chalk = require('chalk')
+const config = require('../vue.config.js')
+const rawArgv = process.argv.slice(2)
+const args = rawArgv.join(' ')
+
+if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
+ const report = rawArgv.includes('--report')
+
+ run(`vue-cli-service build ${args}`)
+
+ const port = 9526
+ const publicPath = config.publicPath
+
+ var connect = require('connect')
+ var serveStatic = require('serve-static')
+ const app = connect()
+
+ app.use(
+ publicPath,
+ serveStatic('./dist', {
+ index: ['index.html', '/']
+ })
+ )
+
+ app.listen(port, function () {
+ console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
+ if (report) {
+ console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
+ }
+
+ })
+} else {
+ run(`vue-cli-service build ${args}`)
+}
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..143cdc8
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,24 @@
+module.exports = {
+ moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
+ transform: {
+ '^.+\\.vue$': 'vue-jest',
+ '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
+ 'jest-transform-stub',
+ '^.+\\.jsx?$': 'babel-jest'
+ },
+ moduleNameMapper: {
+ '^@/(.*)$': '/src/$1'
+ },
+ snapshotSerializers: ['jest-serializer-vue'],
+ testMatch: [
+ '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
+ ],
+ collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
+ coverageDirectory: '/tests/unit/coverage',
+ // 'collectCoverage': true,
+ 'coverageReporters': [
+ 'lcov',
+ 'text-summary'
+ ],
+ testURL: 'http://localhost/'
+}
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..ed079e2
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/mock/index.js b/mock/index.js
new file mode 100644
index 0000000..c514c13
--- /dev/null
+++ b/mock/index.js
@@ -0,0 +1,57 @@
+const Mock = require('mockjs')
+const { param2Obj } = require('./utils')
+
+const user = require('./user')
+const table = require('./table')
+
+const mocks = [
+ ...user,
+ ...table
+]
+
+// for front mock
+// please use it cautiously, it will redefine XMLHttpRequest,
+// which will cause many of your third-party libraries to be invalidated(like progress event).
+function mockXHR() {
+ // mock patch
+ // https://github.com/nuysoft/Mock/issues/300
+ 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
+ // https://expressjs.com/en/4x/api.html#req
+ result = respond({
+ method: type,
+ body: JSON.parse(body),
+ query: param2Obj(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))
+ }
+}
+
+module.exports = {
+ mocks,
+ mockXHR
+}
+
diff --git a/mock/mock-server.js b/mock/mock-server.js
new file mode 100644
index 0000000..8941ec0
--- /dev/null
+++ b/mock/mock-server.js
@@ -0,0 +1,81 @@
+const chokidar = require('chokidar')
+const bodyParser = require('body-parser')
+const chalk = require('chalk')
+const path = require('path')
+const Mock = require('mockjs')
+
+const mockDir = path.join(process.cwd(), 'mock')
+
+function registerRoutes(app) {
+ let mockLastIndex
+ const { mocks } = require('./index.js')
+ const mocksForServer = mocks.map(route => {
+ return responseFake(route.url, route.type, route.response)
+ })
+ for (const mock of mocksForServer) {
+ app[mock.type](mock.url, mock.response)
+ mockLastIndex = app._router.stack.length
+ }
+ const mockRoutesLength = Object.keys(mocksForServer).length
+ return {
+ mockRoutesLength: mockRoutesLength,
+ mockStartIndex: mockLastIndex - mockRoutesLength
+ }
+}
+
+function unregisterRoutes() {
+ Object.keys(require.cache).forEach(i => {
+ if (i.includes(mockDir)) {
+ delete require.cache[require.resolve(i)]
+ }
+ })
+}
+
+// for mock server
+const responseFake = (url, type, respond) => {
+ return {
+ url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
+ type: type || 'get',
+ response(req, res) {
+ console.log('request invoke:' + req.path)
+ res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
+ }
+ }
+}
+
+module.exports = app => {
+ // parse app.body
+ // https://expressjs.com/en/4x/api.html#req.body
+ app.use(bodyParser.json())
+ app.use(bodyParser.urlencoded({
+ extended: true
+ }))
+
+ const mockRoutes = registerRoutes(app)
+ var mockRoutesLength = mockRoutes.mockRoutesLength
+ var mockStartIndex = mockRoutes.mockStartIndex
+
+ // watch files, hot reload mock server
+ chokidar.watch(mockDir, {
+ ignored: /mock-server/,
+ ignoreInitial: true
+ }).on('all', (event, path) => {
+ if (event === 'change' || event === 'add') {
+ try {
+ // remove mock routes stack
+ app._router.stack.splice(mockStartIndex, mockRoutesLength)
+
+ // clear routes cache
+ unregisterRoutes()
+
+ const mockRoutes = registerRoutes(app)
+ mockRoutesLength = mockRoutes.mockRoutesLength
+ mockStartIndex = mockRoutes.mockStartIndex
+
+ console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
+ } catch (error) {
+ console.log(chalk.redBright(error))
+ }
+ }
+ })
+}
diff --git a/mock/table.js b/mock/table.js
new file mode 100644
index 0000000..bd0e013
--- /dev/null
+++ b/mock/table.js
@@ -0,0 +1,29 @@
+const Mock = require('mockjs')
+
+const data = Mock.mock({
+ 'items|30': [{
+ id: '@id',
+ title: '@sentence(10, 20)',
+ 'status|1': ['published', 'draft', 'deleted'],
+ author: 'name',
+ display_time: '@datetime',
+ pageviews: '@integer(300, 5000)'
+ }]
+})
+
+module.exports = [
+ {
+ url: '/vue-admin-template/table/list',
+ type: 'get',
+ response: config => {
+ const items = data.items
+ return {
+ code: 20000,
+ data: {
+ total: items.length,
+ items: items
+ }
+ }
+ }
+ }
+]
diff --git a/mock/user.js b/mock/user.js
new file mode 100644
index 0000000..7555338
--- /dev/null
+++ b/mock/user.js
@@ -0,0 +1,84 @@
+
+const tokens = {
+ admin: {
+ token: 'admin-token'
+ },
+ editor: {
+ token: 'editor-token'
+ }
+}
+
+const users = {
+ 'admin-token': {
+ roles: ['admin'],
+ introduction: 'I am a super administrator',
+ avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+ name: 'Super Admin'
+ },
+ 'editor-token': {
+ roles: ['editor'],
+ introduction: 'I am an editor',
+ avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+ name: 'Normal Editor'
+ }
+}
+
+module.exports = [
+ // user login
+ {
+ url: '/vue-admin-template/user/login',
+ type: 'post',
+ response: config => {
+ const { username } = config.body
+ const token = tokens[username]
+
+ // mock error
+ if (!token) {
+ return {
+ code: 60204,
+ message: 'Account and password are incorrect.'
+ }
+ }
+
+ return {
+ code: 20000,
+ data: token
+ }
+ }
+ },
+
+ // get user info
+ {
+ url: '/vue-admin-template/user/info\.*',
+ type: 'get',
+ response: config => {
+ const { token } = config.query
+ const info = users[token]
+
+ // mock error
+ if (!info) {
+ return {
+ code: 50008,
+ message: 'Login failed, unable to get user details.'
+ }
+ }
+
+ return {
+ code: 20000,
+ data: info
+ }
+ }
+ },
+
+ // user logout
+ {
+ url: '/vue-admin-template/user/logout',
+ type: 'post',
+ response: _ => {
+ return {
+ code: 20000,
+ data: 'success'
+ }
+ }
+ }
+]
diff --git a/mock/utils.js b/mock/utils.js
new file mode 100644
index 0000000..95cc27d
--- /dev/null
+++ b/mock/utils.js
@@ -0,0 +1,25 @@
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+function param2Obj(url) {
+ const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+ if (!search) {
+ return {}
+ }
+ const obj = {}
+ const searchArr = search.split('&')
+ searchArr.forEach(v => {
+ const index = v.indexOf('=')
+ if (index !== -1) {
+ const name = v.substring(0, index)
+ const val = v.substring(index + 1, v.length)
+ obj[name] = val
+ }
+ })
+ return obj
+}
+
+module.exports = {
+ param2Obj
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..799102b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,62 @@
+{
+ "name": "love-tan",
+ "version": "4.4.0",
+ "description": "嘉洛马后台管理系统",
+ "author": "Tan <983196005@qq.com>",
+ "scripts": {
+ "dev": "vue-cli-service serve",
+ "build:prod": "vue-cli-service build",
+ "build:stage": "vue-cli-service build --mode staging",
+ "preview": "node build/index.js --preview",
+ "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
+ "lint": "eslint --ext .js,.vue src",
+ "test:unit": "jest --clearCache && vue-cli-service test:unit",
+ "test:ci": "npm run lint && npm run test:unit"
+ },
+ "dependencies": {
+ "axios": "0.18.1",
+ "core-js": "3.6.5",
+ "element-ui": "2.13.2",
+ "js-cookie": "2.2.0",
+ "normalize.css": "7.0.0",
+ "nprogress": "0.2.0",
+ "path-to-regexp": "2.4.0",
+ "vue": "2.6.10",
+ "vue-router": "3.0.6",
+ "vuex": "3.1.0"
+ },
+ "devDependencies": {
+ "@vue/cli-plugin-babel": "4.4.4",
+ "@vue/cli-plugin-eslint": "4.4.4",
+ "@vue/cli-plugin-unit-jest": "4.4.4",
+ "@vue/cli-service": "4.4.4",
+ "@vue/test-utils": "1.0.0-beta.29",
+ "autoprefixer": "9.5.1",
+ "babel-eslint": "10.1.0",
+ "babel-jest": "23.6.0",
+ "babel-plugin-dynamic-import-node": "2.3.3",
+ "chalk": "2.4.2",
+ "connect": "3.6.6",
+ "eslint": "6.7.2",
+ "eslint-plugin-vue": "6.2.2",
+ "html-webpack-plugin": "3.2.0",
+ "mockjs": "1.0.1-beta3",
+ "runjs": "4.3.2",
+ "sass": "1.26.8",
+ "sass-loader": "8.0.2",
+ "script-ext-html-webpack-plugin": "2.1.3",
+ "serve-static": "1.13.2",
+ "svg-sprite-loader": "4.1.3",
+ "svgo": "1.2.2",
+ "vue-template-compiler": "2.6.10"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions"
+ ],
+ "engines": {
+ "node": ">=8.9",
+ "npm": ">= 3.0.0"
+ },
+ "license": "MIT"
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..10473ef
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,8 @@
+// https://github.com/michael-ciniawsky/postcss-load-config
+
+module.exports = {
+ 'plugins': {
+ // to edit target browsers: use "browserslist" field in package.json
+ 'autoprefixer': {}
+ }
+}
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..b0b305e
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ <%= webpackConfig.name %>
+
+
+
+
+
+
+
diff --git a/public/jialuoma.ico b/public/jialuoma.ico
new file mode 100644
index 0000000000000000000000000000000000000000..c91e1479359ef802410288ac497701852adfb716
GIT binary patch
literal 8849
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
F{{gdRhZ+C?
literal 0
HcmV?d00001
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..ec9032c
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/src/api/table.js b/src/api/table.js
new file mode 100644
index 0000000..2752f52
--- /dev/null
+++ b/src/api/table.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function getList(params) {
+ return request({
+ url: '/vue-admin-template/table/list',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/user.js b/src/api/user.js
new file mode 100644
index 0000000..8ff4389
--- /dev/null
+++ b/src/api/user.js
@@ -0,0 +1,24 @@
+import request from '@/utils/request'
+
+export function login(data) {
+ return request({
+ url: '/vue-admin-template/user/login',
+ method: 'post',
+ data
+ })
+}
+
+export function getInfo(token) {
+ return request({
+ url: '/vue-admin-template/user/info',
+ method: 'get',
+ params: { token }
+ })
+}
+
+export function logout() {
+ return request({
+ url: '/vue-admin-template/user/logout',
+ method: 'post'
+ })
+}
diff --git a/src/assets/404_images/404.png b/src/assets/404_images/404.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d8e2305cc973ad2121403aee4bf08728f76c461
GIT binary patch
literal 98071
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