浏览代码

Merge remote-tracking branch 'origin/feature/route'

# Conflicts:
#	src/views/index/components/login-form-banner.vue
hare8999@163.com 2 年之前
父节点
当前提交
4598b5980c

+ 21 - 178
src/components/Top/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="fx-row fx-bet-cen pl12 pr12 relative" style="line-height: 40px;">
-    <div v-if="path=='/login'" class="fx-row fx-sta-cen">
+    <div v-if="$route.path=='/login'" class="fx-row fx-sta-cen">
       <img class="icon16" src="../../assets/images/icon_tel2.png"/>
       <span class="pl8">服务热线:400-1797-985</span>
       <img class="icon16 ml20" src="../../assets/images/icon_phone.png"/>
@@ -11,19 +11,19 @@
           <p style="width:110px;color:#000;font-size:12px;margin-top:5px;">扫描下载APP</p>
         </div>
       </div>
-      <el-link v-if="!userInfo" href="/pay" type="warning" class="ml20" underline style="font-size: 16px;">
+      <el-link v-if="!isLogin" href="/pay" type="warning" class="ml20" underline style="font-size: 16px;">
         在线购卡
       </el-link>
     </div>
     <div v-else class="fx-row fx-sta-cen">
-      <span @click="to('/login')" class="mr20 pointer">首页</span>
+      <span @click="$router.push('/')" class="mr20 pointer">首页</span>
       <span v-for="(item, index) in visibleMenus" :key="index" class="mr20 pointer"
-            :class="{'f-primary':isActiveMenu(item)}" @click="handleClick(item)">{{ item.meta.title }}</span>
+            :class="{'f-primary':item.path == activeMenu}" @click="handleMenuClick(item)">{{ item.meta.title }}</span>
     </div>
-    <div v-if="userInfo" class="fx-row fx-end-cen">
+    <div v-if="isLogin" class="fx-row fx-end-cen">
       <!--您好!-->
-      <span style="color:#FFA400;">{{ userInfo.nickName }}{{ userInfo.userName }}
-        [{{ userInfo.provinceName }} {{ userInfo.schoolName }}]</span>
+      <span style="color:#FFA400;">{{ currentUser.nickName }}{{ currentUser.userName }}
+        [{{ currentUser.provinceName }} {{ currentUser.schoolName }}]</span>
       <!--,欢迎登录名学金榜-->
       <el-dropdown v-if="roleList.length > 1" @command="handleRoleExchange">
         <span class="el-dropdown-link pointer">[{{ currentRole.roleName }}]</span>
@@ -38,194 +38,37 @@
         </el-dropdown-menu>
       </el-dropdown>
 
-      <img class="icon16" :src="userInfo.avatar"/>
-      <a @click="userTo">个人中心</a>
-      <a style="padding-left:30px;color:#FB731F;" @click="logout">退出登录</a>
+      <img class="icon16" :src="currentUser.avatar"/>
+      <a href="/user/info/userinfo">个人中心</a>
+      <a style="padding-left:30px;color:#FB731F;" @click="LogOut">退出登录</a>
     </div>
   </div>
 </template>
 
 <script>
-import auth from '@/utils/auth'
-import { mapGetters } from 'vuex'
+import { mapActions, mapGetters } from 'vuex'
 import { changeRole } from '@/api/login.js'
-import RouterHelpMixin from '@/router/router-help-mixin'
 
 export default {
-  mixins: [RouterHelpMixin],
   data() {
     return {
-      app: false,
-      path: '',
-      menuList: [],
-      activeLeafMenu: auth.getMenuListAction() || ''
+      app: false
     }
   },
-
   computed: {
-    ...mapGetters(['currentUser', 'currentRole', 'roleList']),
-    userInfo() {
-      if (!auth.getToken()) return null
-      return this.currentUser
-    },
-    // 所有的路由信息
-    routers() {
-      return this.$store.state.permission.topbarRouters
-    },
+    ...mapGetters(['isLogin', 'currentUser', 'currentRole', 'roleList', 'topbarRouters']),
+    // 过滤默认不显示的路由当顶部菜单
     visibleMenus() {
-      return this.menuList.filter((m) => !m.hidden)
+      return this.topbarRouters.filter((m) => !m.hidden)
+    },
+    activeMenu() {
+      return this.$store.getters.activeTopPath
     }
   },
-  created() {
-    this.path = this.$route.path
-  },
-  mounted() {
-    this.menuList = this.topMenus()
-  },
   methods: {
-    isActiveMenu(menu) {
-      return this.activeLeafMenu.includes(menu.path)
-    },
-    logout() {
-      this.$confirm('确定注销并退出系统吗?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        this.$store.dispatch('LogOut').then(() => {
-          this.$router.push({ path: '/login' })
-          window.location.reload()
-        })
-      })
-    },
-    to(url) {
-      this.$router.push({
-        path: url
-      })
-    },
-
-    // 顶部显示菜单
-    topMenus() {
-      let topMenus = []
-      this.routers.map((menu) => {
-        menu.level = 1
-        if (menu.hidden !== true) {
-          // 兼容顶部栏一级菜单内部跳转
-          if (menu.path === '/') {
-            if (menu.children) {
-              topMenus.push(menu.children[0])
-            }
-          } else {
-            topMenus.push(menu)
-          }
-        }
-      })
-      return topMenus
-    },
-    userTo() {
-      //跳转至个人中心
-      this.menuList = this.topMenus()
-      this.menuList.forEach((item) => {
-        if (item.path == '/user') {
-          this.handleClick(item)
-        } else if ('index' == item.path) {
-          this.$emit('userNavTo')
-        }
-      })
-    },
-    handleClick(data) {
-      auth.setMenuTab(data)
-      auth.setActiveMenu(data.path + '/' + data.children[0].path)
-      let item = JSON.parse(JSON.stringify(data))
-      let routes = undefined //三级菜单
-      let second = [] //二级
-      let routesTo = []
-      if (item.children) {
-        //有二级菜单
-        item.children.forEach((item2) => {
-          console.log(item2)
-          if (item2.children) {
-            item2.children.forEach((item3) => {
-              item3.path = item.path + '/' + item2.path + '/' + item3.path
-            })
-            if (!routes && item2.children.length) {
-              console.log(22222222222222)
-              console.log(item2.children)
-              //一级菜单下面第一个有3个菜单的二级菜单
-              routes = item2.children
-              routesTo = item2.children
-            }
-          } else {
-            if (!routes) {
-              routes = []
-            }
-            routesTo = item.children
-          }
-          item2.path = item.path + '/' + item2.path
-          item2.level = 2
-          second.push(item2)
-        })
-        console.log(routes)
-        // let fal = false
-        //选中第一个
-        auth.setActiveMenu(second[0].path)
-        // second.forEach((item) => {
-        //   if (!fal && item.children && item.children.length > 0) {
-        //     auth.setActiveMenu(item.path)
-        //     fal = true
-        //   }
-        // })
-        auth.setMenuTab(second)
-        this.three = true
-        this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
-      } else {
-        //没有二级菜单
-        this.$store.commit('SET_SIDEBAR_ROUTERS', [])
-        this.$router.push({
-          path: item.path
-        })
-      }
-      let path = this.findLeafDescendantPath(data)
-      if (path) {
-        this.$router.push({
-          path: path
-        })
-        auth.setMenuListAction(path)
-        this.activeLeafMenu = path
-      } else {
-      }
-      auth.setMenuList(routes)
-    },
-    toPath(data, path, url) {
-      data.forEach((item) => {
-        if (!path && item.children && item.children.length > 0) {
-          let ac = url ? url + '/' : ''
-          path = this.toPath(item.children, path, ac + item.path)
-        } else if (!path) {
-          let ac = url ? url + '/' : ''
-          path = ac + item.path
-        }
-      })
-      return path
-    },
-    gouAction(data) {
-      // 22.6.7 hht 作废此方法,只处理了有限级跳转
-      if (data && data.length > 0) {
-        if (data[0].children && data[0].children.length > 0) {
-          if (
-            data[0].children[0].children &&
-            data[0].children[0].children.length > 0
-          ) {
-            return data[0].children[0].children.path
-          } else {
-            return data[0].path + '/' + data[0].children[0].path
-          }
-        } else {
-          return data[0].path
-        }
-      } else {
-        return ''
-      }
+    ...mapActions(['LogOut', 'AccessDeepMenu']),
+    handleMenuClick(item) {
+      this.AccessDeepMenu(item)
     },
     handleRoleExchange(roleId) {
       changeRole(roleId).then((_) => {

+ 7 - 332
src/components/TopNav/index.vue

@@ -14,25 +14,10 @@
               <svg-icon :icon-class="item.meta.icon"/>
               {{ item.meta.title }}
             </el-menu-item>
-            <el-menu-item
-              v-if="!(menuList.length > visibleNumber) && !three && user && false"
-              @click="handleOpen('http://8.134.76.179/index.php?m=login&token='+user.code)"
-              index="http://8.134.76.179/index"
-              style="color: #999093"
-            >
-              <svg-icon icon-class="guide"/>
-              学习园地
-            </el-menu-item>
           </div>
         </el-popover>
       </template>
     </template>
-
-    <template></template>
-    <!--    <template v-if="!(menuList.length > visibleNumber)">-->
-    <!--      <el-button v-if="firstNav" style="margin-top:10px;margin-left:10px" size="small" @click.stop="backFirstMenu()" round>返回</el-button>-->
-    <!--    </template>-->
-
     <!-- 顶部菜单超出数量折叠 -->
     <el-submenu index="more" v-if="menuList.length > visibleNumber">
       <template slot="title">更多菜单</template>
@@ -45,89 +30,30 @@
           </el-menu-item>
         </template>
       </template>
-      <el-menu-item
-        v-if=" !three && user && false"
-        @click="handleOpen('http://8.134.76.179/index.php?m=login&token='+user.code)"
-        index="http://8.134.76.179/index"
-      >
-        <svg-icon icon-class="guide"/>
-        学习园地
-      </el-menu-item>
     </el-submenu>
-
-    <!--		<el-button v-if="three" style="margin-top:10px;margin-left:10px" size="small" @click.stop="backMenu()" round>-->
-    <!--			返回-->
-    <!--		</el-button>-->
-    <!-- <el-button v-if="firstNav" style="margin-top:10px;margin-left:10px" size="small" @click.stop="backFirstMenu()" round>返回首页</el-button> -->
   </el-menu>
 </template>
 
 <script>
-import { constantRoutes } from '@/router'
-import path from 'path'
-import auth from '@/utils/auth'
-import Cookies from 'js-cookie'
 import { mapGetters } from 'vuex'
-import RouterHelpMixin from '@/router/router-help-mixin'
 
 export default {
-  mixins: [RouterHelpMixin],
   data() {
     return {
       // 顶部栏初始数
-      visibleNumber: 10,
-      // 是否为首次加载
-      isFrist: false,
-      // 当前激活菜单的 index
-      currentIndex: undefined,
-      menuList: [],
-      three: false,
-      firstNav: true,
-      activeMenu: '',
-      time: null,
-      list1: [
-        { name: '生涯测评', id: 'CareerEva' },
-        { name: '院校库', id: 'UniversitiesColleges' },
-        { name: '专业库', id: 'ProfessLib' },
-        { name: '职业库', id: 'Vocation' },
-        { name: '选科查询', id: 'Subject' },
-        { name: '选科报名', id: 'SubjectSign' },
-        { name: '生涯课程', id: '7' }
-      ],
-      list2: [
-        { name: '高考政策', id: 'gkzc' },
-        { name: '特殊类招生', id: 'tslzs' },
-        { name: '强基计划', id: 'qjjh' },
-        { name: '填报技巧', id: 'tbjq' }
-      ],
-      list3: [
-        { name: '关注的院校', id: '0' },
-        { name: '关注的专业', id: '1' },
-        { name: '生涯测评报告', id: '2' },
-        { name: '我的志愿表', id: '3' }
-      ],
-      list4: [
-        { name: '模拟志愿', id: 'SimulatedVolunteer' },
-        { name: '批次控制线', id: 'batch' },
-        { name: '一分一段', id: 'yfyd' },
-        { name: '投档线', id: 'ShiftLine' },
-        { name: '高考名词', id: 'gkmc' }
-      ],
-      listActive: ''
+      visibleNumber: 10
     }
   },
   computed: {
     ...mapGetters(['currentUser']),
-    user() {
-      return this.currentUser
-    },
     theme() {
       return this.$store.state.settings.theme
     },
-
-    // 所有的路由信息
-    routers() {
-      return this.$store.state.permission.topbarRouters
+    menuList() {
+      return this.$store.getters.middlebarRouters || []
+    },
+    activeMenu() {
+      return this.$store.getters.activeMiddlePath
     }
   },
   beforeMount() {
@@ -136,265 +62,14 @@ export default {
   beforeDestroy() {
     window.removeEventListener('resize', this.setVisibleNumber)
   },
-  mounted() {
-    console.log(new Date().getTime())
-    this.setVisibleNumber()
-    this.menuList = this.topMenus()
-    let menuList = []
-    let routes = []
-    menuList = auth.getMenuTab()
-    routes = auth.getMenuList()
-    console.log(menuList, routes)
-    if (menuList && menuList.length > 0) {
-      this.menuList = menuList
-      this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
-      if (menuList[0].level == 2) {
-        this.three = true
-      }
-      this.activeMenu = auth.getActiveMenu()
-    } else {
-      this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
-      this.gouTo()
-    }
-    console.log(new Date().getTime())
-    if (menuList && menuList[0] && menuList[0].level == 2) {
-      this.firstNav = false
-    }
-    console.log(menuList)
-  },
-  watch: {
-    activeMenu: function(value) {
-      console.log(value)
-      if (value) {
-        auth.setActiveMenu(value)
-      }
-    },
-    $route: function() {
-      this.menuList = auth.getMenuTab()
-      this.activeMenu = auth.getActiveMenu()
-    }
-  },
   methods: {
-    toSecondary(data, item) {
-      auth.setActiveMenu(item.path)
-      this.$router.push({ path: item.path, query: data })
-    },
-    clickEv(data, item) {
-      this.listActive = data.id
-      auth.setActiveMenu(item.path)
-      // this.$router.push({ path: `/career/plan/${data.id}` }).catch(() => { })
-      switch (data.id) {
-        case 'CareerEva':
-          auth.setActiveMenu(item.path)
-          this.$router.push({ path: '/career/plan/CareerEva' }).catch(() => {
-          })
-          break
-        case 'UniversitiesColleges':
-          auth.setActiveMenu(item.path)
-          this.$router
-            .push({ path: '/career/plan/UniversitiesColleges' })
-            .catch(() => {
-            })
-          break
-        case 'ProfessLib':
-          auth.setActiveMenu(item.path)
-          this.$router
-            .push({ path: '/career/plan/MajorLib' })
-            .catch(() => {
-            })
-          break
-        case 'Subject':
-          this.$router.push({ path: '/career/subject/index' }).catch(() => {
-          })
-          break
-        case 'SubjectSign':
-          this.$router
-            .push({ path: '/career/subjectSign/index' })
-            .catch(() => {
-            })
-          break
-        case 'Vocation':
-          this.$router.push({ path: '/career/vocation/index' }).catch(() => {
-          })
-          break
-        case 'batch':
-          this.$router.push({ path: '/career/batch' }).catch(() => {
-          })
-          break
-        case 'yfyd':
-          this.$router.push({ path: '/career/yfyd' }).catch(() => {
-          })
-          break
-        case 'gkmc':
-          this.$router.push({ path: '/career/gkmc/index' }).catch(() => {
-          })
-          break
-        case 'ShiftLine':
-          this.$router.push({ path: '/career/ShiftLine' }).catch(() => {
-          })
-          break
-        case 'SimulatedVolunteer':
-          this.$router
-            .push({ path: '/career/SimulatedVolunteer' })
-            .catch(() => {
-            })
-          break
-        default:
-          this.toSecondary(data, item)
-          break
-      }
-    },
-    gouTo() {
-      let menuList = this.topMenus()
-      let actionMenu = ''
-      menuList.forEach((item, index) => {
-        if (this.$route.query.type == item.path) {
-          this.handleClick(this.menuList[index] || {})
-          if (item.children && item.children.length > 0) {
-            actionMenu = item.path + '/' + item.children[0].path
-          } else {
-            actionMenu = item.path
-          }
-        }
-      })
-      console.log('actionMenu==', actionMenu)
-      let routes = auth.getMenuList()
-      if (routes.length == 0) {
-        this.$router.push({ path: actionMenu })
-        auth.setMenuListAction(actionMenu)
-      } else {
-        console.log('routes', routes)
-        let path = this.findLeafDescendantPath(routes)
-        if (path) {
-          this.$router.push({ path: path })
-          auth.setMenuListAction(path)
-          console.log(new Date().getTime())
-        }
-      }
-    },
-    gouAction(data) {
-      // 22.6.7 hht 作废此方法,只处理了有限级跳转
-      if (data && data.length > 0) {
-        if (data[0].children && data[0].children.length > 0) {
-          if (
-            data[0].children[0].children &&
-            data[0].children[0].children.length > 0
-          ) {
-            return data[0].children[0].children.path
-          } else {
-            return data[0].path + '/' + data[0].children[0].path
-          }
-        } else {
-          return data[0].path
-        }
-      } else {
-        return ''
-      }
-    },
-    backFirstMenu() {
-      this.$router.push('/login')
-    },
-    backMenu() {
-      this.menuList = this.topMenus()
-      auth.setMenuTab(this.menuList)
-      this.firstNav = true
-      this.three = false
-    },
-    handleOpen(url) {
-      window.open(url)
-    },
     handleClick(data) {
-      this.listActive = ''
-      let item = JSON.parse(JSON.stringify(data))
-      let routes = [] //三级菜单
-      let second = [] //二级
-      if (item.level == 1) {
-        debugger
-        //点击一级菜单
-        if (item.children) {
-          //有二级菜单
-          item.children.forEach((item2) => {
-            if (item2.children) {
-              item2.children.forEach((item3) => {
-                item3.path = item.path + '/' + item2.path + '/' + item3.path
-              })
-              if (routes.length == 0 && item2.children.length) {
-                //一级菜单下面第一个有3个菜单的二级菜单
-                routes = item2.children
-                this.activeMenu = item.path + '/' + item2.path //默认值高亮
-              }
-            }
-            item2.path = item.path + '/' + item2.path
-            item2.level = 2
-            second.push(item2)
-          })
-
-          this.menuList = second
-          auth.setMenuTab(second)
-          this.three = true
-          this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
-        } else {
-          //没有二级菜单
-          this.$store.commit('SET_SIDEBAR_ROUTERS', [])
-          this.$router.push({ path: item.path })
-        }
-      } else {
-        auth.setActiveMenu(item.path)
-        if (item.children) {
-          //有三级菜单
-          routes = item.children
-          this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
-          let path = this.toPath(routes, '', '')
-          auth.setMenuListAction(path)
-          this.$router.push({ path: path })
-        } else {
-          routes = []
-          this.$store.commit('SET_SIDEBAR_ROUTERS', [])
-          this.$router.push({ path: item.path })
-        }
-      }
-      auth.setMenuList(routes)
-      this.firstNav = false
-      this.$forceUpdate()
-    },
-    toPath(data, path, url) {
-      data.forEach((item) => {
-        if (!path && item.children && item.children.length > 0) {
-          let ac = url ? url + '/' : ''
-          path = this.toPath(item.children, path, ac + item.path)
-        } else if (!path) {
-          let ac = url ? url + '/' : ''
-          path = ac + item.path
-        }
-      })
-      return path
-    },
-    // 顶部显示菜单
-    topMenus() {
-      let topMenus = []
-      this.routers.map((menu) => {
-        menu.level = 1
-        if (menu.hidden !== true) {
-          // 兼容顶部栏一级菜单内部跳转
-          if (menu.path === '/') {
-            if (menu.children) {
-              topMenus.push(menu.children[0])
-            }
-          } else {
-            topMenus.push(menu)
-          }
-        }
-      })
-      return topMenus
+      this.$store.dispatch('AccessDeepMenu', data)
     },
     // 根据宽度计算设置显示栏数
     setVisibleNumber() {
       const width = document.body.getBoundingClientRect().width / 2
       this.visibleNumber = parseInt(width / 85)
-    },
-
-    ishttp(url) {
-      return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
     }
   }
 }

+ 0 - 1
src/components/mx-transfer-mixin.js

@@ -7,7 +7,6 @@ export default {
   },
   created() {
     this.prevData = JSON.parse(decodeURIComponent(this.$route.query.data || '{}'))
-    console.log('received prev data:', this.prevData)
   },
   methods: {
     // transferUrl方法是给上一个页面用的

+ 22 - 39
src/layout/components/Sidebar/index.vue

@@ -16,72 +16,55 @@
         :collapse-transition="false"
         mode="vertical"
       >
-        <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path  + index" :item="route" :base-path="route.path" />
+        <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path  + index" :item="route"
+                      :base-path="route.path"/>
       </el-menu>
     </el-scrollbar>
   </div>
 </template>
 
 <script>
-import { mapGetters, mapState } from "vuex";
-import Logo from "./Logo";
-import SidebarItem from "./SidebarItem";
-import variables from "@/assets/styles/variables.scss";
-import Cookies from "js-cookie";
-import auth from "@/utils/auth.js";
+import { mapGetters, mapState } from 'vuex'
+import Logo from './Logo'
+import SidebarItem from './SidebarItem'
+import variables from '@/assets/styles/variables.scss'
+
 export default {
   components: { SidebarItem, Logo },
   computed: {
-    ...mapState(["settings"]),
-    ...mapGetters(["sidebarRouters", "sidebar"]),
+    ...mapState(['settings']),
+    ...mapGetters(['sidebarRouters', 'sidebar', 'activeSidePath']),
     activeMenu() {
-      const route = this.$route;
-      const { meta, path } = route;
-
-      let activeMenu = auth.getMenuListAction();
-      if (activeMenu) {
-        return activeMenu;
-      } else {
-        auth.setMenuListAction(route.path);
-      }
-
-      // if set path, the sidebar will highlight the path you set
-      if (meta.activeMenu) {
-        return meta.activeMenu;
-      }
-      return path;
+      return this.activeSidePath
     },
     showLogo() {
-      return this.$store.state.settings.sidebarLogo;
+      return this.$store.state.settings.sidebarLogo
     },
     variables() {
-      return variables;
+      return variables
     },
     isCollapse() {
-      return !this.sidebar.opened;
-    },
+      return !this.sidebar.opened
+    }
   },
   data() {
     return {
-      fal: false,
-    };
-  },
-  watch: {
-    $route: function (route) {},
+      fal: false
+    }
   },
   methods: {
     activeMenuList(data, activeMenu) {
       data.forEach((item) => {
         if (item.path == activeMenu) {
-          this.fal = true;
+          this.fal = true
         }
         if (item.children && item.children.length > 0) {
-          this.activeMenuList(item.children, activeMenu);
+          this.activeMenuList(item.children, activeMenu)
         }
-      });
-    },
-  },
-};
+      })
+    }
+  }
+}
 </script>
 
 <style scoped>

+ 28 - 46
src/permission.js

@@ -11,58 +11,40 @@ NProgress.configure({
 const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/pay', '/question/preview']
 const uaWhiteList = ['/question/preview']
 
-router.beforeEach((to, from, next) => {
+router.beforeEach(async(to, from, next) => {
   NProgress.start()
-  if (auth.getToken()) {
-    if (typeof (to.meta) == "object" && to.meta.hasOwnProperty("isWideScreen")) {
-      store.commit('SET_IS_WIDESCREEN', to.meta.isWideScreen)
-    } else {
-      store.commit('SET_IS_WIDESCREEN', false)
-    }
-    /* has token*/
-    // if (to.path === '/login') {
-    //   next({ path: '/' })
-    //   NProgress.done()
-    // } else {
-    // TODO: hht 22.1.5 这里暂时判断有无有效路由,没有就尝试重构。
-    // 这样不太合适,没有充分利用缓存。
-    if (!store.getters.permission_routes?.length) {
-      // 判断当前用户是否已拉取完user_info信息
-      store.dispatch('GetInfo').then(() => {
-        store.dispatch('GenerateRoutes').then(accessRoutes => {
-          // 根据roles权限生成可访问的路由表
-          router.addRoutes(accessRoutes) // 动态添加可访问路由表
-          next({
-            ...to,
-            replace: true
-          }) // hack方法 确保addRoutes已完成
-        })
-      }).catch(err => {
-        console.log('force logout with error', err);
-        store.dispatch('LogOut').then(() => {
-          //Message.error(err)
-          next({
-            path: '/'
-          })
-        })
-      })
+  const token = auth.getToken()
+  // 白名单检测
+  if (!token && !whiteList.includes(to.path)) {
+    next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
+    NProgress.done()
+    return
+  }
+  try {
+    // 路由智能加载
+    const addRoutes = await store.dispatch('CheckRoutes')
+    // 用户信息智能加载
+    if (token && addRoutes) await store.dispatch('GetInfo')
+    // 加入VUE路由 并跳转
+    if (addRoutes) {
+      next({
+        ...to,
+        replace: true
+      }) // 用replace的方式延迟跳转来保证addRoutes生效了
     } else {
       next()
     }
-    // }
-  } else {
-    // 没有token
-    if (whiteList.indexOf(to.path) !== -1) {
-      // 在免登录白名单,直接进入
-      next()
-    } else {
-      // next()
-      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
-      NProgress.done()
-    }
+  } catch (err) {
+    console.log('force logout with error', err)
+    store.dispatch('LogOut').then(() => {
+      next({
+        path: '/'
+      })
+    })
   }
 })
 
-router.afterEach(() => {
+router.afterEach((to, from) => {
+  store.dispatch('SetLocation', { to, from })
   NProgress.done()
 })

+ 3 - 2
src/router/index.js

@@ -71,7 +71,7 @@ export const constantRoutes = [{
   {
     path: '',
     component: Layout,
-    redirect: 'index',
+    redirect: '/login',
     children: [{
       path: 'index',
       component: (resolve) => require(['@/views/index'], resolve),
@@ -510,7 +510,8 @@ export const constantRoutes = [{
       component: (resolve) => require(['@/views/career/plan/detail'], resolve),
       name: 'careerDetail',
       meta: {
-        title: '播放视频'
+        title: '播放视频',
+        parentPath: '/new-gaokao/careerVideo' // 用于直接跳转时定位菜单
       }
     },
       {

+ 0 - 15
src/router/router-help-mixin.js

@@ -1,15 +0,0 @@
-export default {
-  methods: {
-    findLeafDescendantPath(routeData, ancestorPath = '') {
-      if (!routeData) return ''
-      if (Array.isArray(routeData)) return this.findLeafDescendantPath(routeData.first())
-      const currentPath = routeData.path.startsWith('/')
-        ? routeData.path
-        : ancestorPath + '/' + routeData.path
-      if (!routeData.children?.length) {
-        return currentPath
-      }
-      return this.findLeafDescendantPath(routeData.children.first(), currentPath)
-    }
-  }
-}

+ 8 - 4
src/store/getters.js

@@ -1,5 +1,3 @@
-import store from '@/store/index'
-
 const getters = {
   sidebar: state => state.app.sidebar,
   size: state => state.app.size,
@@ -7,7 +5,8 @@ const getters = {
   visitedViews: state => state.tagsView.visitedViews,
   cachedViews: state => state.tagsView.cachedViews,
   currentUser: state => state.user,
-  token: state => state.user.token,
+  token: state => state.user?.token,
+  isLogin: (state, getters) => !!getters.token,
   avatar: state => state.user.avatar,
   name: state => state.user.name,
   nickName: state => state.user.nickName,
@@ -30,8 +29,13 @@ const getters = {
   period: state => state.user.period,
   permissions: state => state.user.permissions,
   permission_routes: state => state.permission.routes,
+  currentRoute: state => state.permission.currentRoute,
+  activeTopPath: state => state.permission.activeTopPath,
+  activeMiddlePath: state => state.permission.activeMiddlePath,
+  activeSidePath: state => state.permission.activeSidePath,
+  defaultRoutes: state => state.permission.defaultRoutes || [],
   topbarRouters: state => state.permission.topbarRouters,
-  defaultRoutes: state => state.permission.defaultRoutes,
+  middlebarRouters: state => state.permission.middlebarRouters,
   sidebarRouters: state => state.permission.sidebarRouters,
   isWideScreen: state => state.permission.isWideScreen,
   studentParams: state => state.settings.studentParams,

+ 23 - 23
src/store/index.js

@@ -1,23 +1,23 @@
-import Vue from 'vue'
-import Vuex from 'vuex'
-import app from './modules/app'
-import user from './modules/user'
-import tagsView from './modules/tagsView'
-import permission from './modules/permission'
-import settings from './modules/settings'
-import getters from './getters'
-
-Vue.use(Vuex)
-
-const store = new Vuex.Store({
-  modules: {
-    app,
-    user,
-    tagsView,
-    permission,
-    settings
-  },
-  getters
-})
-
-export default store
+import Vue from 'vue'
+import Vuex from 'vuex'
+import app from './modules/app'
+import user from './modules/user'
+import tagsView from './modules/tagsView'
+import permission from './modules/mx-permission'
+import settings from './modules/settings'
+import getters from './getters'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+  modules: {
+    app,
+    user,
+    tagsView,
+    permission,
+    settings
+  },
+  getters
+})
+
+export default store

+ 257 - 0
src/store/modules/mx-permission.js

@@ -0,0 +1,257 @@
+import router, { constantRoutes } from '@/router'
+import { getRouters } from '@/api/menu'
+import Layout from '@/layout/index'
+import ParentView from '@/components/ParentView'
+import auth from '@/utils/auth'
+import { getFrontInitialRouters } from '@/api/system/user'
+
+const permission = {
+  state: {
+    // 路由缓存
+    routeCache: {},
+    // 全部路由 = 本地路由 + 后台路由
+    routes: [],
+    // 后台路由
+    addRoutes: [],
+    // 显示在最顶部的路由 = 后台路由中的一级路由
+    topbarRouters: [],
+    // 中部路由 = topRouters中选中的一级路由的二级子路由
+    middlebarRouters: [],
+    // 边部路由 = middleRouters中选中的二级路由的三级子路由
+    sidebarRouters: [],
+    // 当前路由
+    currentRoute: null,
+    activeTopPath: null,
+    activeMiddlePath: null,
+    activeSidePath: null,
+    // 宽屏
+    isWideScreen: false
+  },
+  mutations: {
+    REMOVE_ROUTES: (state, token) => {
+      state.routes = []
+      state.addRoutes = []
+      state.routeCache = {} // 全部清除
+    },
+    SET_ROUTES: (state, { routes, token }) => {
+      state.addRoutes = routes
+      state.routes = constantRoutes.concat(routes)
+      state.routeCache[token] = routes
+    },
+    SET_TOPBAR_ROUTERS: (state, routes) => {
+      state.topbarRouters = routes
+    },
+    SET_MIDDLEBAR_ROUTERS: (state, routes) => {
+      state.middlebarRouters = routes
+    },
+    SET_SIDEBAR_ROUTERS: (state, routes) => {
+      state.sidebarRouters = routes
+    },
+    SET_IS_WIDESCREEN: (state, trueOrFalse) => {
+      state.isWideScreen = trueOrFalse
+    },
+    SET_CURRENT_ROUTE: (state, route) => {
+      state.currentRoute = route
+    },
+    SET_ACTIVE_TOP_PATH: (state, path) => {
+      state.activeTopPath = path
+    },
+    SET_ACTIVE_MIDDLE_PATH: (state, path) => {
+      state.activeMiddlePath = path
+    },
+    SET_ACTIVE_SIDE_PATH: (state, path) => {
+      state.activeSidePath = path
+    }
+  },
+  actions: {
+    // 生成路由
+    CheckRoutes({ commit, state }, force) {
+      const token = auth.getToken() || ''
+      const cache = state.routeCache[token]
+      let routeAdded = false
+      if (cache && !force) return Promise.resolve(routeAdded) // 缓存不需要返回,已经在外部被调用过store.addRoutes
+      return new Promise(resolve => {
+        // 向后端请求路由数据
+        const routeApi = token ? getRouters : getFrontInitialRouters
+        routeApi().then(res => {
+          const global404 = {
+            path: '*',
+            redirect: '/404',
+            hidden: true
+          }
+          const topRoutes = res.data
+          handleAsyncRouters(topRoutes)
+          const addRoutes = topRoutes.concat([global404])
+
+          // 目前只能确定全局路由与top路由,middle/side需要等路由跳转
+          commit('SET_ROUTES', { routes: addRoutes, token })
+          commit('SET_TOPBAR_ROUTERS', topRoutes)
+          router.addRoutes(addRoutes)
+          routeAdded = !!addRoutes.length
+          resolve(routeAdded)
+        })
+      })
+    },
+    SetLocation({ commit, state }, { to, from }) {
+      // 定位路由,显示合适的菜单
+      // console.log('receive set-location request', to, from)
+      commit('SET_CURRENT_ROUTE', to)
+      commit('SET_IS_WIDESCREEN', to.meta?.isWideScreen)
+      // 现在开始设置top/middle/side三级的当前路由
+      // 有两项任务,1是要设置菜单集合,2是设置当前菜单
+      const topRoutes = state.topbarRouters
+      const ancestors = { fullMatched: false, matches: [] }
+      let targetPath = to.path
+      debugger
+      traceAncestorRoutesInMenus(topRoutes, targetPath, ancestors)
+      if (!ancestors.fullMatched && to.meta?.parentPath) {
+        targetPath = to.meta.parentPath
+        ancestors.matches.length = 0 // clear for re-trace
+        traceAncestorRoutesInMenus(topRoutes, targetPath, ancestors)
+      }
+
+      // 完全匹配,开始操作菜单
+      if (ancestors.fullMatched) {
+        const activeCommits = [
+          {
+            name: 'SET_ACTIVE_TOP_PATH',
+            getPath: (routes, idx) => routes[idx]?.path || ''
+          },
+          {
+            name: 'SET_ACTIVE_MIDDLE_PATH',
+            getPath: (routes, idx) => routes[idx]?.path || ''
+          },
+          {
+            name: 'SET_ACTIVE_SIDE_PATH',
+            getPath: (routes, idx) => (routes[idx] && routes.last())?.path || ''
+          }]
+        // 设置高亮菜单
+        activeCommits.forEach((config, idx) => {
+          commit(config.name, config.getPath(ancestors.matches, idx))
+        })
+        // 设置middle/side菜单集合
+        const topMatch = ancestors.matches[0]
+        if (topMatch) {
+          commit('SET_MIDDLEBAR_ROUTERS', topMatch.children || [])
+          commit('SET_SIDEBAR_ROUTERS', []) // 先清空,可能立即又会被后续代码赋值
+        } else {
+          commit('SET_MIDDLEBAR_ROUTERS', [])
+          commit('SET_SIDEBAR_ROUTERS', [])
+        }
+        const middleMatch = ancestors.matches[1]
+        if (middleMatch) {
+          commit('SET_SIDEBAR_ROUTERS', middleMatch.children || [])
+        }
+      }
+    },
+    RemoveRoutes({ commit }) {
+      commit('REMOVE_ROUTES')
+    },
+    AccessDeepMenu({ commit }, route) {
+      const path = route.meta?.firstLeafPath || route.path
+      router.push(path)
+    }
+  }
+}
+
+function handleAsyncRouters(routes = [], parent = null, level = 0) {
+  // NOTE: hht 22.8.29 解析思路,因为系统菜单全由后台配置,本地静态路由多是子页面等
+  // 1 asyncRoutes尽可能提供多的便利强引用,以用来在匹配到路由之后,快速锁定top/middle/side三级菜单
+  // 2 constantRoutes可以手动去挂载一个弱关联,表示它与后台配置的某个菜单是有关联的,这样在跳转后能正确定位菜单
+  // 其中,1是必要处理步骤;2是充要处理步骤,没有关联即不更改菜单定位(效果不会比现在更差)
+
+  routes.forEach(route => {
+    // 递归处理所有的path, 保证每级路由的path都是绝对地址,方便跳转操作与路由path匹配
+    handleAsyncRouterPath(route, parent)
+    // 递归处理所有的redirect, 让每个非叶子结点路由能redirect到叶子结点
+    handleAsyncRouterRedirect(route)
+    // 递归处理所有的组件属性,从字符串转化为VUE组件
+    handleAsyncRouterComponent(route)
+
+    // 递归挂载本地强引用
+    handleAsyncRouterLocalReference(route, parent, level)
+  })
+}
+
+function handleAsyncRouterPath(route, parent) {
+  if (!route.path) {
+    console.log('handleAsyncRouterPath - route must have `path` value', route.name)
+    return
+  }
+  if (!route.path.startsWith('/')) {
+    route.path = (parent?.path || '') + '/' + route.path
+  }
+  if (route.children?.length) {
+    route.children.forEach(child => handleAsyncRouterPath(child, route))
+  } else {
+    delete route.children
+    delete route.redirect
+  }
+}
+
+function handleAsyncRouterRedirect(route) {
+  // 22.8.30 本来准备利用redirect属性来自动跳转,但后台路由可能会和本地路由重合
+  // 比如`/user`, 后台路由会配置它跳'/user/info',再跳`/user/info/userinfo`
+  // 但因为本地也配置了`/user`,本地静态路由优先级更高,它是没有配置redirect的,结果就是会404
+  // 所以这里直接挂了`_firstLeafPath`, 提供了AccessDeepMenu方法来做跳转
+
+  // 挂载两个后代path, 方便定制菜单
+  const getFirstLeafPath = (routes, deep) => {
+    const firstChild = routes?.first(c => !c.hidden)
+    if (!firstChild) return ''
+    if (!deep) return firstChild.path
+    if (!firstChild.children?.length) return firstChild.path
+    return getFirstLeafPath(firstChild.children, deep)
+  }
+  // 属性挂在meta上可以不受匹配方法等因素的影响,最大限度保留设置
+  route.meta = route.meta || {}
+  route.meta.firstChildPath = getFirstLeafPath(route.children, false)
+  route.meta.firstLeafPath = getFirstLeafPath(route.children, true)
+
+  route.children?.forEach(child => handleAsyncRouterRedirect(child))
+}
+
+function handleAsyncRouterComponent(route) {
+  if (typeof route.component === 'string') {
+    const sharedComponents = { Layout, ParentView }
+    const sharedComponent = sharedComponents[route.component]
+    route.component = sharedComponent || loadView(route.component)
+  }
+  route.children?.forEach(child => handleAsyncRouterComponent(child))
+}
+
+function handleAsyncRouterLocalReference(route, parent, level) {
+  // 属性挂在meta上可以不受匹配方法等因素的影响,最大限度保留设置
+  route.meta = route.meta || {}
+  // 挂parent可逆向追溯, 不能挂反向引用vuex内部会深拷贝!
+  route.meta.parentPath = parent?.path || ''
+  // 挂level可直接定位top/middle/side
+  route.meta.level = level
+  route.children?.forEach(child => handleAsyncRouterLocalReference(child, route, level + 1))
+}
+
+function traceAncestorRoutesInMenus(routes, path, ancestors) {
+  // 从routes中找到目标路径,才算完全成功
+  const fullMath = routes.first(r => r.path == path)
+  if (fullMath) {
+    ancestors.fullMatched = true
+    ancestors.matches.push(fullMath)
+    return
+  }
+  const partialMath = routes.first(r => path.startsWith(r.path))
+  if (partialMath) {
+    ancestors.fullMatched = false
+    ancestors.matches.push(partialMath)
+
+    // 继续往下找
+    if (partialMath.children?.length) {
+      traceAncestorRoutesInMenus(partialMath.children, path, ancestors)
+    }
+  }
+}
+
+export const loadView = (view) => { // 路由懒加载
+  return (resolve) => require([`@/views/${view}`], resolve)
+}
+
+export default permission

+ 28 - 13
src/store/modules/user.js

@@ -1,14 +1,16 @@
-import { login, logout, getInfo } from '@/api/login'
+import { getInfo, login, logout } from '@/api/login'
 import auth from '@/utils/auth'
 import Vue from 'vue'
 import cacheMixin from '@/components/Cache/mx-cache-mixin'
+import { MessageBox } from 'element-ui'
+import router from '@/router'
 
 const user = {
   state: auth.getUserInfo(),
 
   mutations: {
     RELOAD: (state, newInfo) => {
-      console.log('RELOAD this', state, newInfo)
+      console.log('RELOAD - build user reactive features', state, newInfo)
       Object.keys(newInfo).forEach(key => {
         if (!state.hasOwnProperty(key)) {
           // NOTE:使用Vue.set动态添加监控属性
@@ -21,14 +23,20 @@ const user = {
 
   actions: {
     // 登录
-    Login({ commit }, userInfo) {
+    Login({ dispatch, commit, state }, userInfo) {
       const username = userInfo.username.trim()
       const password = userInfo.password
 
       return new Promise((resolve, reject) => {
         login(username, password).then(res => {
           auth.setToken(res.token)
-          resolve()
+          // 登陆后强制更新Info
+          return dispatch('GetInfo')
+        }).then(res => {
+          // 登陆后强制更新routes
+          return dispatch('CheckRoutes', true)
+        }).then(_ => {
+          resolve(state.user)
         }).catch(error => {
           reject(error)
         })
@@ -40,7 +48,8 @@ const user = {
       return new Promise((resolve, reject) => {
         getInfo().then(res => {
           const user = res.data
-          user.avatar = user.avatar || require("@/assets/images/profile.png")
+          user.avatar = user.avatar || require('@/assets/images/profile.png')
+          user.token = auth.getToken() // 这样就可以让token具有响应性(reactive)
           commit('RELOAD', user)
           auth.setUserInfo(user)
           cacheMixin.methods.clearUserCache() // NOTE:纯作为静态方法在调用,有更优雅的方式?
@@ -52,14 +61,20 @@ const user = {
     },
 
     // 退出系统
-    LogOut({ commit, state }) {
-      return new Promise((resolve, reject) => {
-        logout(state.token).then(() => {
-          auth.removeToken()
-          resolve()
-        }).catch(error => {
-          reject(error)
-        })
+    LogOut({ dispatch, commit, state }) {
+      return MessageBox.confirm('确定注销并退出系统吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(_ => {
+        return logout()
+      }).then(_ => {
+        // 清除token,清除真正的登陆状态判定数据
+        auth.removeToken()
+        state.token = ''
+        // 清除routers缓存,则路由劫持事件会根据状态,重新加载路由
+        dispatch('CheckRoutes', true)
+        return router.push('/')
       })
     }
   }

+ 5 - 1
src/views/components/blocks/index-login-check-mixin.js

@@ -17,7 +17,11 @@ export default {
     loginStatusCheck() {
       // 首页统一注入登陆检测方法,未登陆时直接跳至登陆框
       if (this.hasLoginToken()) {
-        return Promise.resolve(true)
+        if (!!this.currentUser?.isBind) return Promise.resolve(true)
+
+        this.dialogVisible = true
+        this.$message.error('请先完善信息!')
+        return Promise.reject(false)
       }
       this.$refs.loginForm?.$el?.scrollIntoView({ behavior: 'smooth' })
       this.$message.error('请先登陆!')

+ 172 - 171
src/views/components/forget-pwd.vue

@@ -1,171 +1,172 @@
-<template>
-  <el-form class="mx-form" ref="form" :model="model" :rules="rules" label-width="80px" label-position="left">
-    <el-form-item prop="mobile" label="手机号码" required>
-      <div class="mx-mobile-send">
-        <el-input v-model="model.mobile" auto-complete="off" placeholder="请输入手机号码">
-        </el-input>
-        <el-button type="primary" class="mx-send" :class="{'inactive':countdown>0}" @click="sendValidateCode">{{countdown>0?`(${countdown})s`:'发送'}}</el-button>
-      </div>
-    </el-form-item>
-    <el-form-item prop="smsCode" label="验证码" required>
-      <el-input v-model="model.smsCode" auto-complete="off" placeholder="请输入验证码">
-      </el-input>
-    </el-form-item>
-    <el-form-item prop="newPassword" label="新密码" required>
-      <el-input type="password" v-model="model.newPassword" auto-complete="new-password" placeholder="请输入新密码">
-      </el-input>
-    </el-form-item>
-    <el-form-item prop="newPwdRepeat" label="确认密码" required>
-      <el-input type="password" v-model="model.newPwdRepeat" auto-complete="new-password" placeholder="请确认新密码">
-      </el-input>
-    </el-form-item>
-    <div class="mx-buttons">
-      <el-button type="primary" @click="submitAction">确认修改</el-button>
-    </div>
-  </el-form>
-</template>
-
-<script>
-import {
-  sendSmsNoValidation,
-  resetCardPassword
-} from "@/api/login";
-
-export default {
-  name: "forgetPassword",
-  data() {
-    return {
-      countdown: 0,
-      model: {
-        mobile: '',
-        smsCode: '',
-        newPassword: '',
-        newPwdRepeat: ''
-      },
-      rules: {
-        mobile: [{
-          required: true,
-          message: '手机号码必填',
-        }, {
-          pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
-          message: '手机号码格式不正确',
-        }],
-        smsCode: [{
-          required: true,
-          message: '验证码必填',
-        }],
-        newPassword: [{
-          required: true,
-          message: '新密码必填',
-        }, {
-          min: 6,
-          max: 20,
-          message: '新密码长度在6-20个字符之间',
-        }],
-        newPwdRepeat: [{
-          required: true,
-          message: '确认密码必填',
-        }, {
-          validator: (rule, value, callback) => {
-            const valid = value == this.model.newPassword
-            const params = valid ? undefined : new Error(rule.message)
-            callback(params)
-          },
-          message: '确认密码与新密码不一致',
-        }]
-      }
-    }
-  },
-  methods: {
-    sendValidateCode: function () {
-      if (this.countdown > 0) return
-      this.$refs.form.validateField('mobile', (error) => {
-        // validate success
-        if (!error) {
-          sendSmsNoValidation({
-            mobile: this.model.mobile,
-            smsType: 1
-          }).then(res => {
-            // send code success
-            this.msgSuccess('发送成功')
-            this.beginCountDown()
-          })
-        } else {
-          this.msgError(error)
-        }
-      })
-    },
-    submitAction: function () {
-      this.$refs.form.validate(valid => {
-        console.log('submitAction', valid)
-        if (valid) {
-          resetCardPassword(this.model).then(res => {
-            this.msgSuccess('新密码修改成功')
-            this.$emit('resetPwdSuccess')
-          })
-        }
-      })
-    },
-    goBack: function () {
-      uni.navigateBack({
-        delta: 1
-      })
-    },
-    beginCountDown() {
-      this.countdown = 90
-      const timer = setInterval(_ => {
-        if (this.countdown == 0) clearInterval(timer)
-        else this.countdown -= 1
-      }, 1000)
-    }
-  }
-}
-</script>
-
-<style scoped>
-.mx-form {
-  padding: 40px 20px;
-  margin-left: 220px;
-  margin-right: 25px;
-  border-radius: 16px;
-}
-
-.mx-back {
-  font-size: 24px;
-  margin-top: 20px;
-  width: 36px;
-  height: 36px;
-  border-radius: 18px;
-  border: 1px solid #999999;
-
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
-
-.mx-mobile-send {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.mx-send {
-  width: 60px;
-  margin-left: 10px;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
-
-.mx-send.inactive {
-  background-color: #aaaaaa;
-  border-color: #aaaaaa;
-}
-
-.mx-buttons {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  margin-top: 40px;
-}
-</style>
+<template>
+  <el-form class="mx-form" ref="form" :model="model" :rules="rules" label-width="80px" label-position="left">
+    <el-form-item prop="mobile" label="手机号码" required>
+      <div class="mx-mobile-send">
+        <el-input v-model="model.mobile" auto-complete="off" placeholder="请输入手机号码">
+        </el-input>
+        <el-button type="primary" class="mx-send" :class="{'inactive':countdown>0}" @click="sendValidateCode">
+          {{ countdown > 0 ? `(${countdown})s` : '发送' }}
+        </el-button>
+      </div>
+    </el-form-item>
+    <el-form-item prop="smsCode" label="验证码" required>
+      <el-input v-model="model.smsCode" auto-complete="off" placeholder="请输入验证码">
+      </el-input>
+    </el-form-item>
+    <el-form-item prop="newPassword" label="新密码" required>
+      <el-input type="password" v-model="model.newPassword" auto-complete="new-password" placeholder="请输入新密码">
+      </el-input>
+    </el-form-item>
+    <el-form-item prop="newPwdRepeat" label="确认密码" required>
+      <el-input type="password" v-model="model.newPwdRepeat" auto-complete="new-password" placeholder="请确认新密码">
+      </el-input>
+    </el-form-item>
+    <div class="mx-buttons">
+      <el-button type="primary" @click="submitAction">确认修改</el-button>
+    </div>
+  </el-form>
+</template>
+
+<script>
+import { resetCardPassword, sendSmsNoValidation } from '@/api/login'
+
+export default {
+  name: 'forgetPassword',
+  data() {
+    return {
+      countdown: 0,
+      model: {
+        mobile: '',
+        smsCode: '',
+        newPassword: '',
+        newPwdRepeat: ''
+      },
+      rules: {
+        mobile: [{
+          required: true,
+          message: '手机号码必填'
+        }, {
+          pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+          message: '手机号码格式不正确'
+        }],
+        smsCode: [{
+          required: true,
+          message: '验证码必填'
+        }],
+        newPassword: [{
+          required: true,
+          message: '新密码必填'
+        }, {
+          min: 6,
+          max: 20,
+          message: '新密码长度在6-20个字符之间'
+        }],
+        newPwdRepeat: [{
+          required: true,
+          message: '确认密码必填'
+        }, {
+          validator: (rule, value, callback) => {
+            const valid = value == this.model.newPassword
+            const params = valid ? undefined : new Error(rule.message)
+            callback(params)
+          },
+          message: '确认密码与新密码不一致'
+        }]
+      }
+    }
+  },
+  methods: {
+    sendValidateCode: function() {
+      if (this.countdown > 0) return
+      this.$refs.form.validateField('mobile', (error) => {
+        // validate success
+        if (!error) {
+          sendSmsNoValidation({
+            mobile: this.model.mobile,
+            smsType: 1
+          }).then(res => {
+            // send code success
+            this.msgSuccess('发送成功')
+            this.beginCountDown()
+          })
+        } else {
+          this.msgError(error)
+        }
+      })
+    },
+    submitAction: function() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          resetCardPassword(this.model).then(res => {
+            this.msgSuccess('新密码修改成功')
+            this.$emit('resetPwdSuccess')
+          })
+        }
+      })
+    },
+    goBack: function() {
+      uni.navigateBack({
+        delta: 1
+      })
+    },
+    beginCountDown() {
+      this.countdown = 90
+      const timer = setInterval(_ => {
+        if (this.countdown == 0) {
+          clearInterval(timer)
+        } else {
+          this.countdown -= 1
+        }
+      }, 1000)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.mx-form {
+  padding: 40px 20px;
+  margin-left: 220px;
+  margin-right: 25px;
+  border-radius: 16px;
+}
+
+.mx-back {
+  font-size: 24px;
+  margin-top: 20px;
+  width: 36px;
+  height: 36px;
+  border-radius: 18px;
+  border: 1px solid #999999;
+
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.mx-mobile-send {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.mx-send {
+  width: 60px;
+  margin-left: 10px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.mx-send.inactive {
+  background-color: #aaaaaa;
+  border-color: #aaaaaa;
+}
+
+.mx-buttons {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: 40px;
+}
+</style>

+ 32 - 31
src/views/evaluating/main.vue

@@ -6,36 +6,36 @@
     <div class="fx-column fx-cen-cen pb20">
       <index-card title="在线试卷" class="mt20 index-block">
         <el-row :gutter="20">
-         <el-col :span="8"  v-for="item in onLinePaper">
-          <div class="wrap-item fx-row jc-between ai-center">
-            <div class="left mr30" >
-              <el-image :src="item.img"></el-image>
-            </div>
-            <div>
-              <div class="fx-row ai-center">
-                <el-image  :src="`${$imgBase}index/daoxue/icon_paper.png`"></el-image>
-                <p class="bold">{{item.title}}</p>
+          <el-col :span="8" v-for="item in onLinePaper">
+            <div class="wrap-item fx-row jc-between ai-center">
+              <div class="left mr30">
+                <el-image :src="item.img"></el-image>
               </div>
-              <p class="mt20 mb20" style="color:#CECECE">少儿数字内容</p>
               <div>
-                <el-button type="primary" @click="$router.push(item.path)">立即查询</el-button>
+                <div class="fx-row ai-center">
+                  <el-image :src="`${$imgBase}index/daoxue/icon_paper.png`"></el-image>
+                  <p class="bold">{{ item.title }}</p>
+                </div>
+                <p class="mt20 mb20" style="color:#CECECE">少儿数字内容</p>
+                <div>
+                  <el-button type="primary" @click="$router.push(item.path)">立即查询</el-button>
+                </div>
               </div>
             </div>
-          </div>
-         </el-col>
+          </el-col>
         </el-row>
       </index-card>
       <index-card title="学情分析" class="mt20 index-block">
         <el-row :gutter="20">
-          <el-col :span="8"  v-for="item in idc" @click="$router.push(item.path)">
+          <el-col :span="8" v-for="item in idc" @click="$router.push(item.path)">
             <div class="wrap-item fx-row jc-between ai-center">
-              <div class="left mr30" >
+              <div class="left mr30">
                 <el-image :src="item.img"></el-image>
               </div>
               <div>
                 <div class="fx-row ai-center">
-                  <el-image  :src="`${$imgBase}index/daoxue/icon_paper.png`"></el-image>
-                  <p class="bold">{{item.title}}</p>
+                  <el-image :src="`${$imgBase}index/daoxue/icon_paper.png`"></el-image>
+                  <p class="bold">{{ item.title }}</p>
                 </div>
                 <p class="mt20 mb20" style="color:#CECECE">少儿数字内容</p>
                 <div>
@@ -55,63 +55,64 @@
 <script>
 import IndexCard from '@/views/index/components/index-card.vue'
 import MxImageWrap from '@/views/questioncenter/components/main-card/mx-image-wrap.vue'
-import RouterHelpMixin from '@/router/router-help-mixin'
 import loginCheckMixin from '@/views/components/blocks/index-login-check-mixin'
+
 export default {
   components: { IndexCard, MxImageWrap },
-  mixins: [RouterHelpMixin, loginCheckMixin],
+  mixins: [loginCheckMixin],
   data() {
     return {
       onLinePaper: [
         {
           title: '个人测评',
-          img:`${this.$imgBase}index/daoxue/personal_eval.png`,
+          img: `${this.$imgBase}index/daoxue/personal_eval.png`,
           path: '/daoxue/evaluating/personal/index_3'
         },
         {
           title: '真题测评',
-          img:`${this.$imgBase}index/daoxue/past_eval.png`,
+          img: `${this.$imgBase}index/daoxue/past_eval.png`,
           path: '/daoxue/evaluating/past/index_5'
         },
         {
           title: '学校测评',
-          img:`${this.$imgBase}index/daoxue/school_eval.png`,
+          img: `${this.$imgBase}index/daoxue/school_eval.png`,
           path: '/daoxue/evaluating/school/index_1'
-        },
+        }
       ],
       idc: [
         {
           title: '个人测评',
-          img:`${this.$imgBase}index/daoxue/personal_idc.png`,
+          img: `${this.$imgBase}index/daoxue/personal_idc.png`,
           path: '/daoxue/idc/eval/index_3'
         },
         {
           title: '真题测评',
-          img:`${this.$imgBase}index/daoxue/past_idc.png`,
+          img: `${this.$imgBase}index/daoxue/past_idc.png`,
           path: '/daoxue/idc/eval/index_5'
         },
         {
           title: '学校测评',
-          img:`${this.$imgBase}index/daoxue/school_idc.png`,
+          img: `${this.$imgBase}index/daoxue/school_idc.png`,
           path: '/daoxue/idc/eval/school/index_1'
-        },
+        }
       ]
     }
   },
-  methods: {
-  }
+  methods: {}
 }
 </script>
 <style scoped lang="scss">
 
-.wrap-item{
+.wrap-item {
   background: #F7F8FD;
   border-radius: 4px;
   padding: 20px 30px 0 30px;
 }
-.right{
+
+.right {
   display: flex;
 }
+
 @media screen and (min-width: 1440px) {
   .index-block {
     width: 1350px;

+ 7 - 8
src/views/index/components/index-card-career.vue

@@ -39,15 +39,14 @@ export default {
     getList() {
       career.listNoToken(this.queryParams).then(res => {
         this.list = res['rows']?.map((item, idx) => {
-          // const path = '/career/plan/detail'
-          const path = '/new-gaokao/careerVideo'
+          const path = '/career/plan/detail'
           const nextParams = {
-            // id: item.id,
-            // aliid: item.aliid,
-            // aliIdType: item.aliIdType,
-            // name: item.name,
-            // count: item.plays,
-            // img: item.pictUrl
+            id: item.id,
+            aliid: item.aliid,
+            aliIdType: item.aliIdType,
+            name: item.name,
+            count: item.plays,
+            img: item.pictUrl
           }
           return {
             title: item.name,

+ 46 - 11
src/views/index/components/login-form-banner.vue

@@ -1,8 +1,6 @@
 <template>
   <div class="fx-row fx-end-cen login-form-container" style="padding: 100px 0;"
-    :style="{backgroundImage: `url(${$imgBase}index/login/banner.png)`} "
-  >
-    <!--    <el-image :src="require('@/assets/images/index/login/banner@2x.png')" class="width100" fit="contain"></el-image>-->
+    :style="{backgroundImage: `url(${$imgBase}index/login/banner.png)`} ">
     <div class="bg-white" style="width:400px; padding:30px; margin-right: 150px;">
       <img style="width: 60%;margin-left:20%;" src="@/assets/images/login_logo.png"/>
       <div class="f-primary text-center mt20 mb40 bold f18" style="letter-spacing: 10px;">
@@ -21,18 +19,17 @@
             type="password"
             auto-complete="off"
             placeholder="密码"
-            @keyup.enter.native="handleLogin"
+            @keyup.enter.native="login"
           >
             <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
           </el-input>
         </el-form-item>
-        <!-- <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> -->
         <div class="fx-row fx-end-cen mb20">
           <label class="pointer f-999 f14" @click="handleForgetPwd">忘记密码?</label>
         </div>
         <el-form-item style="width:100%;">
           <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
-                     @click.native.prevent="handleLogin">
+                     @click.native.prevent="login">
             <span v-if="!loading">登 录</span>
             <span v-else>登 录 中...</span>
           </el-button>
@@ -59,7 +56,7 @@
                                                  src="@/assets/images/icon_jifen.png" alt/>
                                             {{ currentUser.points || 0 }}积分
                                         </span>
-          <span @click="userTo()"
+          <span @click="$router.push('/user/info/userinfo')"
                 style="display:inline-block;width:33%;text-align:center;color:#4055F7;cursor:pointer">
                                             <img style="width: 16px;position: relative;top: 2px;margin-right: 5px;"
                                                  src="@/assets/images/icon_user.png" alt/>个人中心
@@ -81,13 +78,51 @@ import { mapGetters } from 'vuex'
 
 export default {
   name: 'login-form-banner',
-  props: ['isLogin', 'loginForm', 'loginRules', 'loading'],
-  inject: ['userTo', 'handleLogin', 'logout', 'handleForgetPwd'],
+  props: ['loginForm', 'loading'],
+  inject: ['login', 'logout', 'handleForgetPwd'],
   data() {
-    return {}
+    return {
+      loginRules: {
+        relation: [
+          {
+            required: true,
+            trigger: 'blur',
+            message: '请选择学生端或者老师端'
+          }
+        ],
+        grade: [
+          {
+            required: true,
+            trigger: 'blur',
+            message: '请选择学校类别'
+          }
+        ],
+        username: [
+          {
+            required: true,
+            trigger: 'blur',
+            message: '用户名不能为空'
+          }
+        ],
+        password: [
+          {
+            required: true,
+            trigger: 'blur',
+            message: '密码不能为空'
+          }
+        ],
+        code: [
+          {
+            required: true,
+            trigger: 'change',
+            message: '验证码不能为空'
+          }
+        ]
+      }
+    }
   },
   computed: {
-    ...mapGetters(['currentUser', 'schoolName'])
+    ...mapGetters(['currentUser', 'schoolName', 'isLogin'])
   },
   methods: {
     validate: function(cb) {

+ 7 - 12
src/views/index/components/login-top-menus.vue

@@ -14,27 +14,22 @@
 
 <script>
 import loginCheckMixin from '@/views/components/blocks/index-login-interceptor-mixin'
+import { mapActions, mapGetters } from 'vuex'
 
 export default {
   mixins: [loginCheckMixin],
   name: 'login-top-menus',
-  props: {
-    routers: {
-      type: Array,
-      default: () => []
-    }
-  },
-  inject: {
-    to: {
-      default: function() {
-
-      }
+  computed: {
+    ...mapGetters(['topbarRouters']),
+    routers() {
+      return this.topbarRouters.filter(r => !r.hidden)
     }
   },
   methods: {
+    ...mapActions(['AccessDeepMenu']),
     async handleMenuClick(item) {
       await this.loginCheck()
-      this.to(item)
+      this.AccessDeepMenu(item)
     }
   }
 }

+ 24 - 303
src/views/index/login.vue

@@ -1,12 +1,11 @@
 <template>
   <el-container class="login-container">
     <el-header height="40px" style="background: #fff6e8;" class="p0">
-      <top v-if="topLoadin" @userNavTo="userTo"></top>
+      <top></top>
     </el-header>
     <el-main class="p0">
-      <login-top-menus :routers="visibleRouters"></login-top-menus>
-      <login-form-banner ref="loginForm" :is-login="isLogin" :login-form="loginForm" :login-rules="loginRules"
-                         :loading="loading"></login-form-banner>
+      <login-top-menus></login-top-menus>
+      <login-form-banner ref="loginForm" :login-form="loginForm" :loading="loading"></login-form-banner>
       <div class="fx-column fx-cen-cen">
         <index-card-subject-query class="mt20 index-block"/>
         <index-card-elective-test class="mt20 index-block"/>
@@ -29,14 +28,9 @@
 </template>
 
 <script>
-import store from '@/store'
-import router from '@/router'
 import { mapActions, mapGetters } from 'vuex'
-import auth from '@/utils/auth'
-import { getFrontInitialRouters } from '@/api/system/user'
 import forgetPassword from '@/views/components/forget-pwd.vue'
 import CompleteProfile from '@/views/components/complete-profile.vue'
-import RouterHelpMixin from '@/router/router-help-mixin'
 import LoginTopInfo from '@/views/index/components/login-top-info'
 import LoginFormBanner from '@/views/index/components/login-form-banner'
 import LoginTopMenus from '@/views/index/components/login-top-menus'
@@ -50,7 +44,7 @@ import IndexCardCareer from '@/views/index/components/index-card-career'
 import IndexNewsTopWrapper from '@/views/index/components/index-news-top-wrapper'
 
 export default {
-  mixins: [RouterHelpMixin, loginCheckMixin],
+  mixins: [loginCheckMixin],
   components: {
     IndexNewsTopWrapper,
     IndexCardCareer,
@@ -67,9 +61,7 @@ export default {
   },
   provide() {
     return {
-      to: this.to,
-      userTo: this.userTo,
-      handleLogin: this.handleLogin,
+      login: this.login,
       logout: this.logout,
       handleForgetPwd: this.handleForgetPwd
     }
@@ -77,107 +69,13 @@ export default {
   data() {
     return {
       forgetDialogVisiable: false,
-      topLoadin: true,
-      isLogin: auth.getToken(),
       loginObj: {},
       loading: false,
-      gradeLoading: false,
-      navList: [],
       loginForm: {
         username: '',
-        password: '',
-        // rememberMe: false,
-        // code: "",
-        // uuid: "",
-        relation: 1,
-        grade: 2,
-        year: ''
+        password: ''
       },
-      loginRules: {
-        relation: [
-          {
-            required: true,
-            trigger: 'blur',
-            message: '请选择学生端或者老师端'
-          }
-        ],
-        grade: [
-          {
-            required: true,
-            trigger: 'blur',
-            message: '请选择学校类别'
-          }
-        ],
-        username: [
-          {
-            required: true,
-            trigger: 'blur',
-            message: '用户名不能为空'
-          }
-        ],
-        password: [
-          {
-            required: true,
-            trigger: 'blur',
-            message: '密码不能为空'
-          }
-        ],
-        code: [
-          {
-            required: true,
-            trigger: 'change',
-            message: '验证码不能为空'
-          }
-        ]
-      },
-      options: {
-        img: store.getters.avatar //裁剪图片的地址
-      },
-      submitLoading: false,
-      schoolData: [],
-      gradeData: [],
-      classData: [],
-      areaSchoolAndYears: {},
-      isSecd: false,
-      times: 120,
-      form: {
-        username: '',
-        phoneNumber: '',
-        code: '',
-        schoolId: '',
-        gradeId: [],
-        clazzId: []
-      },
-      subjectData: [],
-      dialogVisible: false,
-      id: 0,
-      props: {
-        lazy: true,
-        lazyLoad(node, resolve) {
-          const { level } = node
-          setTimeout(() => {
-            const nodes = Array.from({
-              length: level + 1
-            }).map((item) => {
-              let a = ''
-              if (level == '0') {
-                a = '省'
-              } else if (level == '1') {
-                a = '市'
-              } else {
-                a = '区'
-              }
-              return {
-                value: 1212,
-                label: `选项${a} `,
-                leaf: level >= 2
-              }
-            })
-            // 通过调用resolve将子节点数据返回,通知组件数据加载完成
-            resolve(nodes)
-          }, 1000)
-        }
-      }
+      dialogVisible: false
     }
   },
   computed: {
@@ -185,11 +83,9 @@ export default {
       'isFrontStudent',
       'isFrontTeacher',
       'isFrontMaster',
-      'currentUser'
-    ]),
-    visibleRouters() {
-      return this.navList.filter((r) => r.meta?.title && !r.hidden)
-    }
+      'currentUser',
+      'isLogin'
+    ])
   },
   created() {
     let u = navigator.userAgent
@@ -207,209 +103,25 @@ export default {
           this.loading = true
           this.Login(this.loginObj)
             .then(() => {
-              this.isLogin = true
               this.loading = false
-              this.getUser()
-              this.getNav()
-              // this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
             })
             .catch(() => {
               this.loading = false
             })
         }
       }
-    } else {
-      this.getUser()
-      this.getNav()
     }
   },
   methods: {
-    ...mapActions(['GenerateRoutes', 'Login', 'LogOut', 'GetInfo']),
-    getNav() {
-      console.log(
-        'getNav called',
-        'real menu=' + !!(this.islogin && this.currentUser.isBind),
-        this.currentUser,
-        this.isLogin
-      )
-      if (this.isLogin) {
-        this.GenerateRoutes().then((accessRoutes) => {
-          console.log('GenerateRoutes accessRoutes', accessRoutes)
-          router.addRoutes(accessRoutes) // 动态添加可访问路由表
-          this.navList = JSON.parse(
-            JSON.stringify(
-              this.$store.state.permission.topbarRouters
-            )
-          )
-        })
-      } else {
-        getFrontInitialRouters().then((res) => {
-          this.navList = res.data.map((r) => ({
-            path: r.path,
-            meta: r.meta
-          }))
-        })
-      }
-    },
-    gouAction(data) {
-      // 22.6.7 hht 作废此方法,只处理了有限级跳转
-      if (data && data.length > 0) {
-        if (data[0].children && data[0].children.length > 0) {
-          if (
-            data[0].children[0].children &&
-            data[0].children[0].children.length > 0
-          ) {
-            return data[0].children[0].children.path
-          } else {
-            return data[0].path + '/' + data[0].children[0].path
-          }
-        } else {
-          return data[0].path
-        }
-      } else {
-        return ''
-      }
-    },
-    handleClick(data) {
-      let item = JSON.parse(JSON.stringify(data))
-      let routes = undefined //三级菜单
-      let second = [] //二级
-      let routesTo = []
-      if (item.children) {
-        //有二级菜单
-        item.children.forEach((item2) => {
-          if (item2.children) {
-            item2.children.forEach((item3) => {
-              item3.path =
-                item.path + '/' + item2.path + '/' + item3.path
-            })
-            if (!routes && item2.children.length) {
-              //一级菜单下面第一个有3个菜单的二级菜单
-              routes = item2.children
-              routesTo = item2.children
-            }
-          } else {
-            if (!routes) {
-              routes = []
-            }
-            routesTo = item.children
-          }
-          item2.path = item.path + '/' + item2.path
-          item2.level = 2
-          second.push(item2)
-        })
-        auth.setActiveMenu(second[0].path)
-        // let fal = false
-        // second.forEach((item) => {
-        //   if (!fal && item.children && item.children.length > 0) {
-        //     auth.setActiveMenu(item.path)
-        //     fal = true
-        //   }
-        // })
-
-        auth.setMenuTab(second)
-        this.three = true
-        this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
-      } else {
-        //没有二级菜单
-        this.$store.commit('SET_SIDEBAR_ROUTERS', [])
-        this.$router.push({
-          path: item.path
-        })
-      }
-      let path = this.findLeafDescendantPath(data)
-      if (path) {
-        this.$router.push({
-          path: path
-        })
-        auth.setMenuListAction(path)
-      } else {
-      }
-      auth.setMenuList(routes)
-    },
-    logout() {
-      this.$confirm('确定注销并退出系统吗?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        this.LogOut().then(() => {
-          this.isLogin = false
-          this.getNav()
-          this.topLoadin = false
-          this.loginObj = {}
-          setTimeout(() => {
-            this.topLoadin = true
-            this.$router.push({ path: '/login' })
-          }, 10)
-        })
-      })
-    },
-    getUser() {
-      if (!this.isLogin) return
-      this.GetInfo().then((response) => {
-        this.dialogVisible = !this.currentUser.isBind
-        this.topLoadin = false
-        setTimeout(() => {
-          this.topLoadin = true
-        }, 10)
-      })
-    },
-    userTo() {
-      //跳转至个人中心
-      if (this.isLogin && !this.currentUser.isBind) {
-        this.dialogVisible = true
-        this.$message.error('请先完善信息!')
-        return
-      }
-      const pcRouter = this.navList.find((r) => r.path == '/user')
-      if (pcRouter) this.to(pcRouter)
-    },
-    to(url) {
-      console.log('will go to', url)
-      auth.removeMenuTab()
-      auth.removeMenuList()
-      if (this.isLogin && this.currentUser.isBind) {
-        if (url == '/login') {
-          window.location.reload()
-          return
-        }
-        if (
-          url ==
-          '/index?type=http://8.134.76.179/index.php?m=login&token=94c750ea0f7f41d7753327792e937589'
-        ) {
-          window.open(
-            'http://8.134.76.179/index.php?m=login&token=' +
-            this.currentUser.code
-          )
-        } else if (url == '/user/profile') {
-          this.$router.push({
-            path: url
-          })
-        } else {
-          this.handleClick(url)
-        }
-      } else if (this.isLogin && this.currentUser.isBind) {
-        this.dialogVisible = true
-        this.$message.error('请先完善信息!')
-      } else {
-        this.$message.error('请先登陆!')
-      }
-    },
-    handleForgetPwd() {
-      this.forgetDialogVisiable = true
-    },
-    handleLogin() {
+    ...mapActions(['CheckRoutes', 'Login', 'LogOut', 'GetInfo']),
+    login() {
       this.$refs.loginForm.validate((valid) => {
         if (valid) {
           this.loading = true
           this.Login(this.loginForm)
             .then(() => {
-              this.isLogin = true
               this.loading = false
-              this.getUser()
-              this.getNav()
-              // this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
+              this.loginStatusCheck()
             })
             .catch(() => {
               this.loading = false
@@ -417,9 +129,18 @@ export default {
         }
       })
     },
-    handleProfileCompleted() {
+    logout() {
+      this.LogOut().then(() => {
+        this.loginObj = {}
+      })
+    },
+    handleForgetPwd() {
+      this.forgetDialogVisiable = true
+    },
+    async handleProfileCompleted() {
       this.dialogVisible = !this.currentUser.isBind
-      this.getNav() //重新获取菜单
+      await this.CheckRoutes(true)
+      await this.GetInfo()
     }
   }
 }

文件差异内容过多而无法显示
+ 0 - 701
src/views/login.vue


部分文件因为文件数量过多而无法显示