mo 5 jaren geleden
bovenliggende
commit
36db9f70d3

+ 1 - 4
.eslintignore

@@ -1,4 +1 @@
-build/*.js
-src/assets
-public
-dist
+*

+ 182 - 181
.eslintrc.js

@@ -9,190 +9,191 @@ module.exports = {
     node: true,
     es6: true,
   },
-  extends: ['plugin:vue/recommended', 'eslint:recommended'],
+  // 'plugin:vue/recommended', 'eslint:recommended'
+  extends: [],
 
   // 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']
+    //   "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']
   }
 }

+ 2 - 2
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "vue-admin-template",
+  "name": "dy-grade-manager",
   "version": "4.2.1",
   "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
   "author": "Pan <panfree23@gmail.com>",
@@ -61,4 +61,4 @@
     "> 1%",
     "last 2 versions"
   ]
-}
+}

+ 29 - 10
src/api/user.js

@@ -1,24 +1,43 @@
 import request from '@/utils/request'
+import qs from 'qs'
 
-export function login(data) {
+export function login (data) {
   return request({
-    url: '/user/login',
+    url: '/api-auth/usernameLogin',
+    // url: '/user/login',
     method: 'post',
-    data
+    data: qs.stringify(data)
   })
 }
 
-export function getInfo(token) {
+export function getInfo () {
   return request({
-    url: '/user/info',
-    method: 'get',
-    params: { token }
+    url: '/api-user/employee/queryUserInfo',
+    method: 'get'
+  })
+}
+// 登出
+export function logout (data) {
+  return request({
+    url: '/api-auth/exit',
+    method: 'post',
+    data: qs.stringify(data)
   })
 }
 
-export function logout() {
+// 获取首页数据
+export function getIndex (data) {
   return request({
-    url: '/user/logout',
-    method: 'post'
+    url: '/api-web/index',
+    method: 'get',
+    params: data
+  })
+}
+// 刷新token
+export function getRefreshToken (data) {
+  return request({
+    url: '/api-auth/refreshToken',
+    method: 'post',
+    data: qs.stringify(data)
   })
 }

+ 16 - 12
src/components/Breadcrumb/index.vue

@@ -1,9 +1,13 @@
 <template>
-  <el-breadcrumb class="app-breadcrumb" separator="/">
+  <el-breadcrumb class="app-breadcrumb"
+                 separator="/">
     <transition-group name="breadcrumb">
-      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
-        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
-        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
+      <el-breadcrumb-item v-for="(item,index) in levelList"
+                          :key="item.path">
+        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1"
+              class="no-redirect">{{ item.meta.title }}</span>
+        <a v-else
+           @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
       </el-breadcrumb-item>
     </transition-group>
   </el-breadcrumb>
@@ -13,45 +17,45 @@
 import pathToRegexp from 'path-to-regexp'
 
 export default {
-  data() {
+  data () {
     return {
       levelList: null
     }
   },
   watch: {
-    $route() {
+    $route () {
       this.getBreadcrumb()
     }
   },
-  created() {
+  created () {
     this.getBreadcrumb()
   },
   methods: {
-    getBreadcrumb() {
+    getBreadcrumb () {
       // only show routes with meta.title
       let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
       const first = matched[0]
 
       if (!this.isDashboard(first)) {
-        matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
+        matched = [{ path: '/dashboard', meta: { title: 'Dashboard' } }].concat(matched)
       }
 
       this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
     },
-    isDashboard(route) {
+    isDashboard (route) {
       const name = route && route.name
       if (!name) {
         return false
       }
       return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
     },
-    pathCompile(path) {
+    pathCompile (path) {
       // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
       const { params } = this.$route
       var toPath = pathToRegexp.compile(path)
       return toPath(params)
     },
-    handleLink(item) {
+    handleLink (item) {
       const { redirect, path } = item
       if (redirect) {
         this.$router.push(redirect)

+ 6 - 3
src/layout/components/AppMain.vue

@@ -1,6 +1,7 @@
 <template>
   <section class="app-main">
-    <transition name="fade-transform" mode="out-in">
+    <transition name="fade-transform"
+                mode="out-in">
       <router-view :key="key" />
     </transition>
   </section>
@@ -10,7 +11,7 @@
 export default {
   name: 'AppMain',
   computed: {
-    key() {
+    key () {
       return this.$route.path
     }
   }
@@ -24,8 +25,10 @@ export default {
   width: 100%;
   position: relative;
   overflow: hidden;
+  background-color: #f0f2f5;
+  padding: 24px;
 }
-.fixed-header+.app-main {
+.fixed-header + .app-main {
   padding-top: 50px;
 }
 </style>

+ 52 - 38
src/layout/components/Navbar.vue

@@ -1,34 +1,45 @@
 <template>
-  <div class="navbar">
-    <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
-
-    <breadcrumb class="breadcrumb-container" />
-
-    <div class="right-menu">
-      <el-dropdown class="avatar-container" trigger="click">
-        <div class="avatar-wrapper">
-          <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
-          <i class="el-icon-caret-bottom" />
-        </div>
-        <el-dropdown-menu slot="dropdown" class="user-dropdown">
-          <router-link to="/">
-            <el-dropdown-item>
-              Home
+  <div>
+    <div class="navbar">
+      <hamburger :is-active="sidebar.opened"
+                 class="hamburger-container"
+                 @toggleClick="toggleSideBar" />
+
+      <div class="left-menu">机构名称</div>
+      <div class="right-menu">
+        <el-dropdown class="avatar-container"
+                     trigger="click">
+          <div class="avatar-wrapper">
+            <img :src="avatar+'?imageView2/1/w/80/h/80'"
+                 class="user-avatar">
+            <i class="el-icon-caret-bottom" />
+          </div>
+          <el-dropdown-menu slot="dropdown"
+                            class="user-dropdown">
+            <router-link to="/">
+              <el-dropdown-item>
+                Home
+              </el-dropdown-item>
+            </router-link>
+            <a target="_blank"
+               href="https://github.com/PanJiaChen/vue-admin-template/">
+              <el-dropdown-item>Github</el-dropdown-item>
+            </a>
+            <a target="_blank"
+               href="https://panjiachen.github.io/vue-element-admin-site/#/">
+              <el-dropdown-item>Docs</el-dropdown-item>
+            </a>
+            <el-dropdown-item divided>
+              <span style="display:block;"
+                    @click="logout">Log Out</span>
             </el-dropdown-item>
-          </router-link>
-          <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
-            <el-dropdown-item>Github</el-dropdown-item>
-          </a>
-          <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
-            <el-dropdown-item>Docs</el-dropdown-item>
-          </a>
-          <el-dropdown-item divided>
-            <span style="display:block;" @click="logout">Log Out</span>
-          </el-dropdown-item>
-        </el-dropdown-menu>
-      </el-dropdown>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </div>
     </div>
+    <breadcrumb class="breadcrumb-container" />
   </div>
+
 </template>
 
 <script>
@@ -48,10 +59,10 @@ export default {
     ])
   },
   methods: {
-    toggleSideBar() {
+    toggleSideBar () {
       this.$store.dispatch('app/toggleSideBar')
     },
-    async logout() {
+    async logout () {
       await this.$store.dispatch('user/logout')
       this.$router.push(`/login?redirect=${this.$route.fullPath}`)
     }
@@ -60,30 +71,33 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+.breadcrumb-container {
+  padding: 0 24px;
+}
 .navbar {
   height: 50px;
   overflow: hidden;
   position: relative;
   background: #fff;
-  box-shadow: 0 1px 4px rgba(0,21,41,.08);
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
 
   .hamburger-container {
     line-height: 46px;
     height: 100%;
     float: left;
     cursor: pointer;
-    transition: background .3s;
-    -webkit-tap-highlight-color:transparent;
+    transition: background 0.3s;
+    -webkit-tap-highlight-color: transparent;
 
     &:hover {
-      background: rgba(0, 0, 0, .025)
+      background: rgba(0, 0, 0, 0.025);
     }
   }
 
-  .breadcrumb-container {
-    float: left;
+  .left-menu {
+    height: 100%;
+    line-height: 50px;
   }
-
   .right-menu {
     float: right;
     height: 100%;
@@ -103,10 +117,10 @@ export default {
 
       &.hover-effect {
         cursor: pointer;
-        transition: background .3s;
+        transition: background 0.3s;
 
         &:hover {
-          background: rgba(0, 0, 0, .025)
+          background: rgba(0, 0, 0, 0.025);
         }
       }
     }

+ 20 - 8
src/layout/components/Sidebar/Logo.vue

@@ -1,12 +1,24 @@
 <template>
-  <div class="sidebar-logo-container" :class="{'collapse':collapse}">
+  <div class="sidebar-logo-container"
+       :class="{'collapse':collapse}">
     <transition name="sidebarLogoFade">
-      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo">
-        <h1 v-else class="sidebar-title">{{ title }} </h1>
+      <router-link v-if="collapse"
+                   key="collapse"
+                   class="sidebar-logo-link"
+                   to="/">
+        <img v-if="logo"
+             :src="logo"
+             class="sidebar-logo">
+        <h1 v-else
+            class="sidebar-title">{{ title }} </h1>
       </router-link>
-      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo">
+      <router-link v-else
+                   key="expand"
+                   class="sidebar-logo-link"
+                   to="/">
+        <img v-if="logo"
+             :src="logo"
+             class="sidebar-logo">
         <h1 class="sidebar-title">{{ title }} </h1>
       </router-link>
     </transition>
@@ -22,9 +34,9 @@ export default {
       required: true
     }
   },
-  data() {
+  data () {
     return {
-      title: 'Vue Admin Template',
+      title: '考级管理系统',
       logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
     }
   }

+ 49 - 41
src/layout/index.vue

@@ -1,6 +1,9 @@
 <template>
-  <div :class="classObj" class="app-wrapper">
-    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+  <div :class="classObj"
+       class="app-wrapper">
+    <div v-if="device==='mobile'&&sidebar.opened"
+         class="drawer-bg"
+         @click="handleClickOutside" />
     <sidebar class="sidebar-container" />
     <div class="main-container">
       <div :class="{'fixed-header':fixedHeader}">
@@ -24,16 +27,16 @@ export default {
   },
   mixins: [ResizeMixin],
   computed: {
-    sidebar() {
+    sidebar () {
       return this.$store.state.app.sidebar
     },
-    device() {
+    device () {
       return this.$store.state.app.device
     },
-    fixedHeader() {
+    fixedHeader () {
       return this.$store.state.settings.fixedHeader
     },
-    classObj() {
+    classObj () {
       return {
         hideSidebar: !this.sidebar.opened,
         openSidebar: this.sidebar.opened,
@@ -43,51 +46,56 @@ export default {
     }
   },
   methods: {
-    handleClickOutside() {
+    handleClickOutside () {
       this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
     }
   }
 }
 </script>
-
+<style lang="scss">
+.m-container {
+  background-color: #fff;
+  min-height: calc(100vh - 100px);
+}
+</style>
 <style lang="scss" scoped>
-  @import "~@/styles/mixin.scss";
-  @import "~@/styles/variables.scss";
-
-  .app-wrapper {
-    @include clearfix;
-    position: relative;
-    height: 100%;
-    width: 100%;
-    &.mobile.openSidebar{
-      position: fixed;
-      top: 0;
-    }
-  }
-  .drawer-bg {
-    background: #000;
-    opacity: 0.3;
-    width: 100%;
-    top: 0;
-    height: 100%;
-    position: absolute;
-    z-index: 999;
-  }
+@import "~@/styles/mixin.scss";
+@import "~@/styles/variables.scss";
 
-  .fixed-header {
+.app-wrapper {
+  @include clearfix;
+  position: relative;
+  height: 100%;
+  width: 100%;
+  &.mobile.openSidebar {
     position: fixed;
     top: 0;
-    right: 0;
-    z-index: 9;
-    width: calc(100% - #{$sideBarWidth});
-    transition: width 0.28s;
   }
+}
+.drawer-bg {
+  background: #000;
+  opacity: 0.3;
+  width: 100%;
+  top: 0;
+  height: 100%;
+  position: absolute;
+  z-index: 999;
+}
 
-  .hideSidebar .fixed-header {
-    width: calc(100% - 54px)
-  }
+.fixed-header {
+  position: fixed;
+  top: 0;
+  right: 0;
+  z-index: 9;
+  width: calc(100% - #{$sideBarWidth});
+  transition: width 0.28s;
+}
 
-  .mobile .fixed-header {
-    width: 100%;
-  }
+.hideSidebar .fixed-header {
+  width: calc(100% - 54px);
+}
+
+.mobile .fixed-header {
+  width: 100%;
+}
 </style>

+ 42 - 42
src/permission.js

@@ -10,53 +10,53 @@ NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
 const whiteList = ['/login'] // no redirect whitelist
 
-router.beforeEach(async(to, from, next) => {
-  // start progress bar
-  NProgress.start()
+// router.beforeEach(async (to, from, next) => {
+//   // start progress bar
+//   NProgress.start()
 
-  // set page title
-  document.title = getPageTitle(to.meta.title)
+//   // set page title
+//   document.title = getPageTitle(to.meta.title)
 
-  // determine whether the user has logged in
-  const hasToken = getToken()
+//   // determine whether the user has logged in
+//   const hasToken = getToken()
 
-  if (hasToken) {
-    if (to.path === '/login') {
-      // if is logged in, redirect to the home page
-      next({ path: '/' })
-      NProgress.done()
-    } else {
-      const hasGetUserInfo = store.getters.name
-      if (hasGetUserInfo) {
-        next()
-      } else {
-        try {
-          // get user info
-          await store.dispatch('user/getInfo')
+//   if (hasToken) {
+//     if (to.path === '/login') {
+//       // if is logged in, redirect to the home page
+//       next({ path: '/' })
+//       NProgress.done()
+//     } else {
+//       const hasGetUserInfo = store.getters.name
+//       if (hasGetUserInfo) {
+//         next()
+//       } else {
+//         try {
+//           // get user info
+//           await store.dispatch('user/getInfo')
+//           next()
+//         } catch (error) {
+//           // remove token and go to login page to re-login
+//           await store.dispatch('user/resetToken')
+//           Message.error('获取用户信息失败')
 
-          next()
-        } catch (error) {
-          // remove token and go to login page to re-login
-          await store.dispatch('user/resetToken')
-          Message.error(error || 'Has Error')
-          next(`/login?redirect=${to.path}`)
-          NProgress.done()
-        }
-      }
-    }
-  } else {
-    /* has no token*/
+//           next(`/login?redirect=${to.path}`)
+//           NProgress.done()
+//         }
+//       }
+//     }
+//   } else {
+//     /* has no token*/
 
-    if (whiteList.indexOf(to.path) !== -1) {
-      // in the free login whitelist, go directly
-      next()
-    } else {
-      // other pages that do not have permission to access are redirected to the login page.
-      next(`/login?redirect=${to.path}`)
-      NProgress.done()
-    }
-  }
-})
+//     if (whiteList.indexOf(to.path) !== -1) {
+//       // in the free login whitelist, go directly
+//       next()
+//     } else {
+//       // other pages that do not have permission to access are redirected to the login page.
+//       next(`/login?redirect=${to.path}`)
+//       NProgress.done()
+//     }
+//   }
+// })
 
 router.afterEach(() => {
   // finish progress bar

+ 16 - 5
src/router/index.js

@@ -149,13 +149,24 @@ export const constantRoutes = [
   },
 
   {
-    path: 'external-link',
+    path: '/systemManager',
     component: Layout,
+    redirect: '/systemManager/setOragin',
+    name: 'setOragin',
+    meta: { title: '系统管理', icon: 'example' },
     children: [
       {
-        path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
-        meta: { title: 'External Link', icon: 'link' }
-      }
+        path: 'setOragin',
+        name: 'setOragin',
+        component: () => import('@/views/systemManager/setOragin'),
+        meta: { title: '机构设置', icon: 'table' }
+      },
+      // {
+      //   path: 'tree',
+      //   name: 'Tree',
+      //   component: () => import('@/views/tree/index'),
+      //   meta: { title: 'Tree', icon: 'tree' }
+      // }
     ]
   },
 
@@ -172,7 +183,7 @@ const createRouter = () => new Router({
 const router = createRouter()
 
 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
-export function resetRouter() {
+export function resetRouter () {
   const newRouter = createRouter()
   router.matcher = newRouter.matcher // reset router
 }

+ 1 - 1
src/settings.js

@@ -1,6 +1,6 @@
 module.exports = {
 
-  title: 'Vue Admin Template',
+  title: '考级管理系统',
 
   /**
    * @type {boolean} true | false

+ 54 - 25
src/store/modules/user.js

@@ -1,13 +1,15 @@
 import { login, logout, getInfo } from '@/api/user'
 import { getToken, setToken, removeToken } from '@/utils/auth'
 import { resetRouter } from '@/router'
-
+// import qs from 'qs'
 const state = {
   token: getToken(),
   name: '',
-  avatar: ''
+  avatar: '',
+  organ: '',
+  organName: ''
 }
-
+// organName
 const mutations = {
   SET_TOKEN: (state, token) => {
     state.token = token
@@ -17,53 +19,80 @@ const mutations = {
   },
   SET_AVATAR: (state, avatar) => {
     state.avatar = avatar
+  },
+  SET_ORGAN: (state, organ) => {
+    state.organ = organ
+  },
+  SET_ORGANNAME: (state, organName) => {
+    state.organName = organName
+  },
+  SET_REFRESH_TOKEN: (state, refreshToken) => {
+    state.refreshToken = refreshToken
+  },
+  SET_EXPIRES_IN: (state, expiresIn) => {
+    state.expiresIn = expiresIn
   }
 }
 
 const actions = {
   // user login
-  login({ commit }, userInfo) {
+  login ({ commit }, userInfo) {
+
     const { username, password } = userInfo
     return new Promise((resolve, reject) => {
-      login({ username: username.trim(), password: password }).then(response => {
+      // qs.stringify({ username: username.trim(), password: password, clientId: 'app', clientSecret: 'app' })
+      // { username: username.trim(), password: password }
+
+      login({ username: username.trim(), password: password, clientId: 'system', clientSecret: 'system', tenantId: 'master' }).then(response => {
         const { data } = response
-        commit('SET_TOKEN', data.token)
-        setToken(data.token)
-        resolve()
+        if (response.code == 200) {
+          const token = data.authentication.token_type + ' ' + data.authentication.access_token
+          commit('SET_REFRESH_TOKEN', data.authentication.refresh_token)
+          commit('SET_EXPIRES_IN', data.authentication.expires_in)
+          commit('SET_TOKEN', token)
+          setToken(token)
+          resolve()
+        }
       }).catch(error => {
         reject(error)
       })
     })
   },
-
-  // get user info
-  getInfo({ commit, state }) {
+  // get 获取用户信息
+  getInfo ({ commit, state }) {
     return new Promise((resolve, reject) => {
       getInfo(state.token).then(response => {
-        const { data } = response
-
-        if (!data) {
-          reject('Verification failed, please Login again.')
+        if (response.code == 200) {
+          const data = response
+          if (!data.data) {
+            reject('获取用户信息错误,请重新登录')
+          }
+          const username = data.data.realName || data.data.username
+          const avatar = data.data.avatar
+          const organ = data.data.organId
+          const organName = data.data.organName
+          // const { name, avatar } = data
+          commit('SET_NAME', username)
+          commit('SET_AVATAR', avatar)
+          commit('SET_ORGAN', organ)
+          commit('SET_ORGANNAME', organName)
+          resolve(data)
         }
-
-        const { name, avatar } = data
-
-        commit('SET_NAME', name)
-        commit('SET_AVATAR', avatar)
-        resolve(data)
       }).catch(error => {
         reject(error)
+        return
       })
     })
   },
 
-  // user logout
-  logout({ commit, state }) {
+  // 登出
+  logout ({ commit }) {
     return new Promise((resolve, reject) => {
-      logout(state.token).then(() => {
+      logout().then(() => {
         commit('SET_TOKEN', '')
         removeToken()
         resetRouter()
+        commit('SET_NAME', '')
         resolve()
       }).catch(error => {
         reject(error)
@@ -72,7 +101,7 @@ const actions = {
   },
 
   // remove token
-  resetToken({ commit }) {
+  resetToken ({ commit }) {
     return new Promise(resolve => {
       commit('SET_TOKEN', '')
       removeToken()

+ 2 - 2
src/utils/get-page-title.js

@@ -1,8 +1,8 @@
 import defaultSettings from '@/settings'
 
-const title = defaultSettings.title || 'Vue Admin Template'
+const title = defaultSettings.title || '考级管理系统'
 
-export default function getPageTitle(pageTitle) {
+export default function getPageTitle (pageTitle) {
   if (pageTitle) {
     return `${pageTitle} - ${title}`
   }

+ 20 - 0
src/utils/loading.js

@@ -0,0 +1,20 @@
+import { Loading } from 'element-ui'
+let loading // 定义loading变量
+
+function startLoading () { // 使用Element loading-start 方法
+  loading = Loading.service({
+    lock: true,
+    fullscreen: true,
+    text: '加载中……',
+    background: 'rgba(0, 0, 0, 0.7)'
+  })
+}
+function endLoading () {
+  // 使用Element loading-close 方法
+  loading.close()
+}
+
+export default {
+  startLoading,
+  endLoading
+}

+ 119 - 44
src/utils/request.js

@@ -1,85 +1,160 @@
+import ElementUI from 'element-ui'
 import axios from 'axios'
-import { MessageBox, Message } from 'element-ui'
+import { Message } from 'element-ui'
 import store from '@/store'
 import { getToken } from '@/utils/auth'
+// import { Loading } from 'element-ui'
+import load from '@/utils/loading'
+import router from '@/router/index'
+import Vue from 'vue'
+const showMessage = Symbol('showMessage')
+class DonMessage {
+  success (options, single = true) {
+    this[showMessage]('success', options, single)
+  }
+  warning (options, single = true) {
+    this[showMessage]('warning', options, single)
+  }
+  info (options, single = true) {
+    this[showMessage]('info', options, single)
+  }
+  error (options, single = true) {
+    this[showMessage]('error', options, single)
+  }
+  [showMessage] (type, options, single) {
+    if (single) {
+      // 判断是否已存在Message
+      if (document.getElementsByClassName('el-message').length === 0) {
+        Message[type](options)
+      }
+    } else {
+      Message[type](options)
+    }
+  }
+}
+
+Vue.use(ElementUI)
+// 命名根据需要,DonMessage只是在文章中使用
+Vue.prototype.$message = new DonMessage()
+
+const vue = new Vue()
+
+// let loading        //定义loading变量
+
+// function startLoading () {    //使用Element loading-start 方法
+//   loading = Loading.service({
+//     lock: true,
+//     fullscreen: true,
+//     text: '加载中……',
+//     background: 'rgba(0, 0, 0, 0.7)'
+//   })
+// }
+// function endLoading () {
+//   //使用Element loading-close 方法
+//   loading.close();
+// }
+// 那么 showFullScreenLoading() tryHideFullScreenLoading() 要干的事儿就是将同一时刻的请求合并。
+// 声明一个变量 needLoadingRequestCount,每次调用showFullScreenLoading方法 needLoadingRequestCount + 1。
+// 调用tryHideFullScreenLoading()方法,needLoadingRequestCount - 1。needLoadingRequestCount为 0 时,结束 loading。
+let needLoadingRequestCount = 0
+function showFullScreenLoading () {
+  if (needLoadingRequestCount === 0) {
+    load.startLoading()
+  }
+  needLoadingRequestCount++
+}
+
+function tryHideFullScreenLoading () {
+  if (needLoadingRequestCount <= 0) return
+  needLoadingRequestCount--
+  if (needLoadingRequestCount === 0) {
+    load.endLoading()
+  }
+}
+
+// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
 
 // create an axios instance
 const service = axios.create({
-  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
+  baseURL: '', // url = base url + request url
   // withCredentials: true, // send cookies when cross-domain requests
-  timeout: 5000 // request timeout
+  timeout: 180000 // request timeout
 })
-
+// { fullscreen: true, text: '努力加载中', spinner: 'el-icon-loading' }
 // request interceptor
 service.interceptors.request.use(
   config => {
     // do something before request is sent
-
+    showFullScreenLoading()
     if (store.getters.token) {
       // let each request carry token
       // ['X-Token'] is a custom headers key
       // please modify it according to the actual situation
       config.headers['Authorization'] = getToken()
+      // config.headers['content-type'] = "application/x-www-form-urlencoded"
     }
     return config
   },
   error => {
     // do something with request error
-    console.log(error) // for debug
+    tryHideFullScreenLoading()
     return Promise.reject(error)
   }
 )
 
 // response interceptor
 service.interceptors.response.use(
-  /**
-   * If you want to get http information such as headers or status
-   * Please return  response => response
-  */
-
-  /**
-   * Determine the request status by custom code
-   * Here is just an example
-   * You can also judge the status by HTTP Status Code
-   */
-  response => {
-    const res = response.data
-
-    // if the custom code is not 20000, it is judged as an error.
-    if (res.code !== 20000) {
-      Message({
-        message: res.message || 'Error',
-        type: 'error',
-        duration: 5 * 1000
-      })
-
+  res => {
+    // res.code !== 200
+    if (res.data) {
+      const data = JSON.parse(JSON.stringify(res.data))
       // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
-      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
-        // to re-login
-        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
-          confirmButtonText: 'Re-Login',
-          cancelButtonText: 'Cancel',
-          type: 'warning'
-        }).then(() => {
+      if (data.code == 401 || data.code == 403) {
+        // Message({
+        //   message: `登陆过期,请重新登录!`,
+        //   type: 'error',
+        //   duration: 5 * 1000
+        // })
+        vue.$message.error(`登陆过期,请重新登录!`)
+        setTimeout(() => {
+          tryHideFullScreenLoading()
           store.dispatch('user/resetToken').then(() => {
             location.reload()
           })
-        })
+        }, 1000)
+        return
+      }
+      if (data.code == 404) {
+        router.push('/404')
+      }
+      if (data.code != 200) {
+        // Message({
+        //   message: data.msg || `请求失败code码为${ data.code }`,
+        //   type: 'error',
+        //   duration: 5 * 1000
+        // })
+        const str = data.msg || `请求失败code码为${data.code}`
+
+        vue.$message.error(str)
+        tryHideFullScreenLoading()
+        return Promise.reject(new Error(data.msg || 'Error'))
+      } else {
+        tryHideFullScreenLoading()
+        return data
       }
-      return Promise.reject(new Error(res.message || 'Error'))
     } else {
-      return res
+      tryHideFullScreenLoading()
+      return Promise.reject()
     }
   },
   error => {
-    console.log('err' + error) // for debug
-    Message({
-      message: error.message,
-      type: 'error',
-      duration: 5 * 1000
-    })
+    if (error.message == 'Network Error') {
+      vue.$message.error('网络异常,请检查网络连接')
+    } else {
+      vue.$message.error(error.message)
+    }
+    tryHideFullScreenLoading()
     return Promise.reject(error)
   }
 )
-
 export default service

+ 4 - 4
src/utils/validate.js

@@ -6,7 +6,7 @@
  * @param {string} path
  * @returns {Boolean}
  */
-export function isExternal(path) {
+export function isExternal (path) {
   return /^(https?:|mailto:|tel:)/.test(path)
 }
 
@@ -14,7 +14,7 @@ export function isExternal(path) {
  * @param {string} str
  * @returns {Boolean}
  */
-export function validUsername(str) {
-  const valid_map = ['admin', 'editor']
-  return valid_map.indexOf(str.trim()) >= 0
+export function validUsername (str) {
+
+  return str.length > 0
 }

+ 21 - 12
src/views/404.vue

@@ -2,19 +2,28 @@
   <div class="wscn-http404-container">
     <div class="wscn-http404">
       <div class="pic-404">
-        <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
-        <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
-        <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
-        <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
+        <img class="pic-404__parent"
+             src="@/assets/404_images/404.png"
+             alt="404">
+        <img class="pic-404__child left"
+             src="@/assets/404_images/404_cloud.png"
+             alt="404">
+        <img class="pic-404__child mid"
+             src="@/assets/404_images/404_cloud.png"
+             alt="404">
+        <img class="pic-404__child right"
+             src="@/assets/404_images/404_cloud.png"
+             alt="404">
       </div>
       <div class="bullshit">
-        <div class="bullshit__oops">OOPS!</div>
+        <!-- <div class="bullshit__oops">OOPS!</div>
         <div class="bullshit__info">All rights reserved
           <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
-        </div>
+        </div> -->
         <div class="bullshit__headline">{{ message }}</div>
-        <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
-        <a href="" class="bullshit__return-home">Back to home</a>
+        <!-- <div class="bullshit__info">页面未找到</div> -->
+        <a href=""
+           class="bullshit__return-home">返回首页</a>
       </div>
     </div>
   </div>
@@ -25,16 +34,16 @@
 export default {
   name: 'Page404',
   computed: {
-    message() {
-      return 'The webmaster said that you can not enter this page...'
+    message () {
+      return '页面未找到!'
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-.wscn-http404-container{
-  transform: translate(-50%,-50%);
+.wscn-http404-container {
+  transform: translate(-50%, -50%);
   position: absolute;
   top: 40%;
   left: 50%;

+ 39 - 21
src/views/form/index.vue

@@ -1,46 +1,64 @@
 <template>
   <div class="app-container">
-    <el-form ref="form" :model="form" label-width="120px">
+    <el-form ref="form"
+             :model="form"
+             label-width="120px">
       <el-form-item label="Activity name">
-        <el-input v-model="form.name" />
+        <el-input v-model.trim="form.name" />
       </el-form-item>
       <el-form-item label="Activity zone">
-        <el-select v-model="form.region" placeholder="please select your zone">
-          <el-option label="Zone one" value="shanghai" />
-          <el-option label="Zone two" value="beijing" />
+        <el-select v-model.trim="form.region"
+                   placeholder="please select your zone">
+          <el-option label="Zone one"
+                     value="shanghai" />
+          <el-option label="Zone two"
+                     value="beijing" />
         </el-select>
       </el-form-item>
       <el-form-item label="Activity time">
         <el-col :span="11">
-          <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
+          <el-date-picker v-model.trim="form.date1"
+                          type="date"
+                          placeholder="Pick a date"
+                          style="width: 100%;" />
         </el-col>
-        <el-col :span="2" class="line">-</el-col>
+        <el-col :span="2"
+                class="line">-</el-col>
         <el-col :span="11">
-          <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
+          <el-time-picker v-model.trim="form.date2"
+                          type="fixed-time"
+                          placeholder="Pick a time"
+                          style="width: 100%;" />
         </el-col>
       </el-form-item>
       <el-form-item label="Instant delivery">
-        <el-switch v-model="form.delivery" />
+        <el-switch v-model.trim="form.delivery" />
       </el-form-item>
       <el-form-item label="Activity type">
-        <el-checkbox-group v-model="form.type">
-          <el-checkbox label="Online activities" name="type" />
-          <el-checkbox label="Promotion activities" name="type" />
-          <el-checkbox label="Offline activities" name="type" />
-          <el-checkbox label="Simple brand exposure" name="type" />
+        <el-checkbox-group v-model.trim="form.type">
+          <el-checkbox label="Online activities"
+                       name="type" />
+          <el-checkbox label="Promotion activities"
+                       name="type" />
+          <el-checkbox label="Offline activities"
+                       name="type" />
+          <el-checkbox label="Simple brand exposure"
+                       name="type" />
         </el-checkbox-group>
       </el-form-item>
       <el-form-item label="Resources">
-        <el-radio-group v-model="form.resource">
+        <el-radio-group v-model.trim="form.resource">
           <el-radio label="Sponsor" />
           <el-radio label="Venue" />
         </el-radio-group>
       </el-form-item>
       <el-form-item label="Activity form">
-        <el-input v-model="form.desc" type="textarea" />
+        <el-input v-model.trim="form.desc"
+                  type="textarea" />
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" @click="onSubmit">Create</el-button>
+        <el-button type="primary"
+                   @click="onSubmit">Create</el-button>
         <el-button @click="onCancel">Cancel</el-button>
       </el-form-item>
     </el-form>
@@ -49,7 +67,7 @@
 
 <script>
 export default {
-  data() {
+  data () {
     return {
       form: {
         name: '',
@@ -64,10 +82,10 @@ export default {
     }
   },
   methods: {
-    onSubmit() {
+    onSubmit () {
       this.$message('submit!')
     },
-    onCancel() {
+    onCancel () {
       this.$message({
         message: 'cancel!',
         type: 'warning'
@@ -78,7 +96,7 @@ export default {
 </script>
 
 <style scoped>
-.line{
+.line {
   text-align: center;
 }
 </style>

+ 96 - 44
src/views/login/index.vue

@@ -1,53 +1,61 @@
 <template>
   <div class="login-container">
-    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
-
+    <el-form ref="loginForm"
+             :model="loginForm"
+             :rules="loginRules"
+             class="login-form"
+             auto-complete="on"
+             label-position="left">
       <div class="title-container">
-        <h3 class="title">Login Form</h3>
+        <h3 class="title">
+          考级管理系统
+        </h3>
       </div>
 
       <el-form-item prop="username">
         <span class="svg-container">
           <svg-icon icon-class="user" />
         </span>
-        <el-input
-          ref="username"
-          v-model="loginForm.username"
-          placeholder="Username"
-          name="username"
-          type="text"
-          tabindex="1"
-          auto-complete="on"
-        />
+        <el-input ref="username"
+                  v-model.trim="loginForm.username"
+                  placeholder="请输入用户名"
+                  name="username"
+                  type="text"
+                  tabindex="1"
+                  auto-complete="on" />
       </el-form-item>
 
       <el-form-item prop="password">
         <span class="svg-container">
           <svg-icon icon-class="password" />
         </span>
-        <el-input
-          :key="passwordType"
-          ref="password"
-          v-model="loginForm.password"
-          :type="passwordType"
-          placeholder="Password"
-          name="password"
-          tabindex="2"
-          auto-complete="on"
-          @keyup.enter.native="handleLogin"
-        />
-        <span class="show-pwd" @click="showPwd">
+        <el-input :key="passwordType"
+                  ref="password"
+                  v-model.trim="loginForm.password"
+                  :type="passwordType"
+                  placeholder="请输入密码"
+                  name="password"
+                  tabindex="2"
+                  auto-complete="on"
+                  @keyup.enter.native="handleLogin" />
+        <span class="show-pwd"
+              @click="showPwd">
           <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
         </span>
       </el-form-item>
 
-      <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
-
-      <div class="tips">
-        <span style="margin-right:20px;">username: admin</span>
-        <span> password: any</span>
+      <el-button :loading="loading"
+                 type="primary"
+                 style="width:100%;margin-bottom:30px;"
+                 @click.native.prevent="handleLogin">
+        登 录
+      </el-button>
+      <div class="remberBox"
+           @click="saveUserInfo">
+        <div class="dotWrap">
+          <div :class="isSaveUserInfo?'active':''" />
+        </div>记住密码
       </div>
-
     </el-form>
   </div>
 </template>
@@ -57,25 +65,25 @@ import { validUsername } from '@/utils/validate'
 
 export default {
   name: 'Login',
-  data() {
+  data () {
     const validateUsername = (rule, value, callback) => {
       if (!validUsername(value)) {
-        callback(new Error('Please enter the correct user name'))
+        callback(new Error('请输入用户名'))
       } else {
         callback()
       }
     }
     const validatePassword = (rule, value, callback) => {
       if (value.length < 6) {
-        callback(new Error('The password can not be less than 6 digits'))
+        callback(new Error('密码必须大于六位'))
       } else {
         callback()
       }
     }
     return {
       loginForm: {
-        username: 'admin',
-        password: '111111'
+        username: '',
+        password: ''
       },
       loginRules: {
         username: [{ required: true, trigger: 'blur', validator: validateUsername }],
@@ -83,19 +91,24 @@ export default {
       },
       loading: false,
       passwordType: 'password',
-      redirect: undefined
+      redirect: undefined,
+      isSaveUserInfo: true
     }
   },
   watch: {
     $route: {
-      handler: function(route) {
+      handler: function (route) {
         this.redirect = route.query && route.query.redirect
       },
       immediate: true
     }
   },
+  mounted () {
+    this.loginForm.username = localStorage.getItem('username')
+    this.loginForm.password = localStorage.getItem('password')
+  },
   methods: {
-    showPwd() {
+    showPwd () {
       if (this.passwordType === 'password') {
         this.passwordType = ''
       } else {
@@ -105,7 +118,14 @@ export default {
         this.$refs.password.focus()
       })
     },
-    handleLogin() {
+    handleLogin () {
+      if (this.isSaveUserInfo) {
+        localStorage.setItem('username', this.loginForm.username)
+        localStorage.setItem('password', this.loginForm.password)
+      } else {
+        localStorage.setItem('username', '')
+        localStorage.setItem('password', '')
+      }
       this.$refs.loginForm.validate(valid => {
         if (valid) {
           this.loading = true
@@ -120,6 +140,9 @@ export default {
           return false
         }
       })
+    },
+    saveUserInfo () {
+      this.isSaveUserInfo = !this.isSaveUserInfo
     }
   }
 }
@@ -129,8 +152,8 @@ export default {
 /* 修复input 背景不协调 和光标变色 */
 /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
 
-$bg:#283443;
-$light_gray:#fff;
+$bg: #283443;
+$light_gray: #fff;
 $cursor: #fff;
 
 @supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
@@ -173,9 +196,9 @@ $cursor: #fff;
 </style>
 
 <style lang="scss" scoped>
-$bg:#2d3a4b;
-$dark_gray:#889aa4;
-$light_gray:#eee;
+$bg: #2d3a4b;
+$dark_gray: #889aa4;
+$light_gray: #eee;
 
 .login-container {
   min-height: 100%;
@@ -233,5 +256,34 @@ $light_gray:#eee;
     cursor: pointer;
     user-select: none;
   }
+  .remberBox {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-end;
+    margin-bottom: 50px;
+    align-items: center;
+    cursor: pointer;
+    color: #fff;
+    .dotWrap {
+      width: 18px;
+      height: 18px;
+      border: 1px solid #fff;
+      border-radius: 50%;
+      margin-right: 8px;
+      position: relative;
+      overflow: hidden;
+
+      .active {
+        width: 10px;
+        height: 10px;
+        background-color: #fff;
+        border-radius: 50%;
+        overflow: hidden;
+        position: absolute;
+        top: 3px;
+        left: 3px;
+      }
+    }
+  }
 }
 </style>

+ 2 - 1
src/views/nested/menu1/index.vue

@@ -1,6 +1,7 @@
 <template>
   <div style="padding:30px;">
-    <el-alert :closable="false" title="menu 1">
+    <el-alert :closable="false"
+              title="menu 1">
       <router-view />
     </el-alert>
   </div>

+ 51 - 0
src/views/systemManager/setOragin.vue

@@ -0,0 +1,51 @@
+<template>
+  <div class="m-container">
+    <div class="infoWrap">
+      <div class="head">基本信息</div>
+      <div class="formWrap">
+        <div class="left">
+          <el-form :inline="true"
+                   label-width="100px">
+            <el-form-item label="机构名称">
+              <el-input></el-input>
+            </el-form-item>
+            <el-form-item label="管理员">
+              <el-input></el-input>
+            </el-form-item>
+            <el-form-item label="登录密码">
+              <el-input></el-input>
+            </el-form-item>
+            <el-form-item label="管理员电话">
+              <el-input></el-input>
+            </el-form-item>
+          </el-form>
+        </div>
+
+      </div>
+
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  data () {
+    return {}
+  },
+  mounted () { }
+}
+</script>
+<style lang="scss" scoped>
+.infoWrap {
+  .head {
+    height: 50px;
+    line-height: 50px;
+    background-color: #1e2b36;
+    padding: 0 24px;
+    color: #fff;
+  }
+  .formWrap {
+    padding: 0 24px;
+    width: 500px;
+  }
+}
+</style>

+ 12 - 12
src/views/tree/index.vue

@@ -1,15 +1,15 @@
 <template>
   <div class="app-container">
-    <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
+    <el-input v-model.trim="filterText"
+              placeholder="Filter keyword"
+              style="margin-bottom:30px;" />
 
-    <el-tree
-      ref="tree2"
-      :data="data2"
-      :props="defaultProps"
-      :filter-node-method="filterNode"
-      class="filter-tree"
-      default-expand-all
-    />
+    <el-tree ref="tree2"
+             :data="data2"
+             :props="defaultProps"
+             :filter-node-method="filterNode"
+             class="filter-tree"
+             default-expand-all />
 
   </div>
 </template>
@@ -17,7 +17,7 @@
 <script>
 export default {
 
-  data() {
+  data () {
     return {
       filterText: '',
       data2: [{
@@ -62,13 +62,13 @@ export default {
     }
   },
   watch: {
-    filterText(val) {
+    filterText (val) {
       this.$refs.tree2.filter(val)
     }
   },
 
   methods: {
-    filterNode(value, data) {
+    filterNode (value, data) {
       if (!value) return true
       return data.label.indexOf(value) !== -1
     }

+ 50 - 11
vue.config.js

@@ -2,11 +2,11 @@
 const path = require('path')
 const defaultSettings = require('./src/settings.js')
 
-function resolve(dir) {
+function resolve (dir) {
   return path.join(__dirname, dir)
 }
 
-const name = defaultSettings.title || 'vue Admin Template' // page title
+const name = defaultSettings.title || '考级管理系统' // page title
 
 // If your port is set to 80,
 // use administrator privileges to execute the command line.
@@ -14,7 +14,13 @@ const name = defaultSettings.title || 'vue Admin Template' // page title
 // You can change the port by the following methods:
 // port = 9528 npm run dev OR npm run dev --port = 9528
 const port = process.env.port || process.env.npm_config_port || 9528 // dev port
-
+// let target = 'https://online.dayaedu.com' //线上
+// let target = 'http://testadm.dayaedu.com/' //test环境
+// let target = 'http://192.168.3.27:8000' // 箭河
+const target = 'http://192.168.3.28:8000' // 邹璇
+// let target = 'http://192.168.3.8:8000' //勇哥
+// const target = 'http://admin.dayaedu.com' // 测试服
+// let target = 'http://192.168.3.151:8080' // 乔
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
 module.exports = {
   /**
@@ -39,15 +45,48 @@ module.exports = {
     proxy: {
       // change xxx-api/login => mock/login
       // detail: https://cli.vuejs.org/config/#devserver-proxy
-      [process.env.VUE_APP_BASE_API]: {
-        target: `http://127.0.0.1:${port}/mock`,
+      // http://47.99.212.176:8000
+      // http://192.168.3.28:8000
+      '/api-auth': {
+        target: target,
+        changeOrigin: true,
+        pathRewrite: {
+          '^api-auth': ''
+        }
+      },
+      '/api-task': {
+        target: target,
         changeOrigin: true,
         pathRewrite: {
-          ['^' + process.env.VUE_APP_BASE_API]: ''
+          '^api-task': ''
         }
+      },
+      '/api-user': {
+        target: target,
+        changeOrigin: true,
+        pathRewrite: {
+          '^api-user': ''
+        }
+      },
+      '/api-cms': {
+        target: target,
+        changeOrigin: true,
+        pathRewrite: {
+          '^api-cms': ''
+        }
+      },
+      '/api-teacher': {
+        target: target,
+        changeOrigin: true,
+        pathRewrite: {
+          '^api-teacher': ''
+        }
+      },
+      '/jiari': {
+        target: 'http://tool.bitefu.net',
+        changeOrigin: true
       }
-    },
-    after: require('./mock/mock-server.js')
+    }
   },
   configureWebpack: {
     // provide the app's title in webpack's name field, so that
@@ -59,7 +98,7 @@ module.exports = {
       }
     }
   },
-  chainWebpack(config) {
+  chainWebpack (config) {
     config.plugins.delete('preload') // TODO: need test
     config.plugins.delete('prefetch') // TODO: need test
 
@@ -92,7 +131,7 @@ module.exports = {
       .end()
 
     config
-    // https://webpack.js.org/configuration/devtool/#development
+      // https://webpack.js.org/configuration/devtool/#development
       .when(process.env.NODE_ENV === 'development',
         config => config.devtool('cheap-source-map')
       )
@@ -104,7 +143,7 @@ module.exports = {
             .plugin('ScriptExtHtmlWebpackPlugin')
             .after('html')
             .use('script-ext-html-webpack-plugin', [{
-            // `runtime` must same as runtimeChunk name. default is `runtime`
+              // `runtime` must same as runtimeChunk name. default is `runtime`
               inline: /runtime\..*\.js$/
             }])
             .end()