Quellcode durchsuchen

feat: 删除原先登录、注册、管理员界面,添加统一登录逻辑

ChenYangfan vor 6 Jahren
Ursprung
Commit
da2ef09289

+ 44 - 6
src/App.vue

@@ -16,30 +16,53 @@
 import GlobalMessage from '@/components/Basic/GlobalMessage'
 import SlideUpTransition from '@/animations/SlideUpTransition'
 import { mapState } from 'vuex'
-import { userTypeNaming } from '@/enums/user-type'
+import userType, { userTypeNaming } from '@/enums/user-type'
+// import { jumpToLogin } from '@/server/auth'
+import { SET_TOKEN, SET_USER_INFO } from '@/store/types/main-types'
+import { getUserInfo } from '@/server/user'
 
 export default {
   components: { GlobalMessage, SlideUpTransition },
   computed: {
     ...mapState({
-      userInfo: state => state.main.userInfo
+      userInfo: state => state.main.userInfo,
+      token: state => state.main.token
     })
   },
+  watch: {
+    $route: {
+      handler (newValue) {
+        const token = newValue.query['id_token']
+        if (token && token !== this.token) {
+          localStorage.setItem('token', token)
+          this.$store.commit(SET_TOKEN, { token })
+          this.fetchUserInfo()
+        }
+      },
+      immediate: true
+    }
+  },
   created () {
+    this.$axios.interceptors.request.use(config => {
+      config.headers['Authorization'] = this.token
+      return config
+    })
+
     // 拦截 401 - 无登录信息 前往登录界面
     this.$axios.interceptors.response.use((response) => {
       return response
     }, (error) => {
       if (error.response.status === 401 && this.$route.matched.some(record => record.meta.roles)) {
-        this.$router.push({ name: 'login' })
+        // this.$router.push({ name: 'login' })
+        // jumpToLogin()
       }
       return Promise.reject(error)
     })
 
     this.$router.beforeEach((to, from, next) => {
-      if (to.matched.some(record => (record.meta.roles && !record.meta.roles.some(role => role === this.userInfo.type.toLowerCase())))) {
-        this.$setInfoMessage('所前往的页面需要使用' + userTypeNaming[this.userInfo.type] + '身份登录')
-        next({ name: this.userInfo.type.toLowerCase() })
+      if (to.matched.some(record => (record.meta.roles && !record.meta.roles.some(role => role === this.userInfo.role.toLowerCase())))) {
+        this.$setInfoMessage('所前往的页面需要使用' + userTypeNaming[this.userInfo.role] + '身份登录')
+        next({ name: this.userInfo.role.toLowerCase() })
       } else {
         next()
       }
@@ -54,6 +77,21 @@ export default {
     window.addEventListener('beforeunload', () => {
       sessionStorage.setItem('store', JSON.stringify(this.$store.state))
     })
+  },
+  mounted () {
+    this.fetchUserInfo()
+  },
+  methods: {
+    fetchUserInfo () {
+      getUserInfo().then(res => {
+        this.$store.commit(SET_USER_INFO, { userInfo: res })
+        if (res.role === userType.student) {
+          this.$router.push({ name: 'student-explore' })
+        } else {
+          this.$router.push({ name: 'teacher-explore' })
+        }
+      }).catch(err => this.$setErrorMessage(err.response.data.msg))
+    }
   }
 }
 </script>

+ 2 - 2
src/components/Details/CourseDetail.vue

@@ -12,7 +12,7 @@
       <div>创建时间:</div>
       <div>{{createTime}}</div>
     </div>
-    <div v-if="userInfo.type === 'TEACHER'">
+    <div v-if="userInfo.role === 'TEACHER'">
       <div>选课码:</div>
       <div>{{code}}</div>
     </div>
@@ -36,7 +36,7 @@ export default {
     }
   },
   mounted () {
-    if (this.userInfo.type === 'TEACHER') {
+    if (this.userInfo.role === 'TEACHER') {
       getCourseCode({ courseId: this.course.id }).then(res => {
         this.code = res
       }).catch(err => {

+ 1 - 1
src/components/Discussion/CComment.vue

@@ -10,7 +10,7 @@
       </div>
       <div class="comment-content">{{comment.content}}</div>
       <div class="comment-author">{{ createTime }} | 作者:{{comment.userName}} <span
-        class="role">{{userTypeNaming[comment.userType]}}</span></div>
+        class="role">{{userTypeNaming[comment.userRole]}}</span></div>
       <comment-tool-bar
         :top-number="comment.topNumber || ''"
         :user-id="comment.userId" :has-reply="comment.reply || ''"

+ 1 - 1
src/components/Discussion/CommentToolBar.vue

@@ -37,7 +37,7 @@ export default {
       return this.userId === this.userInfo.id
     },
     isTeacher () {
-      return this.userInfo.type === 'TEACHER'
+      return this.userInfo.role === 'TEACHER'
     }
   },
   methods: {

+ 12 - 6
src/router/admin.js

@@ -1,6 +1,12 @@
-export default [{
-  meta: { roles: ['admin'] },
-  path: '/admin',
-  name: 'admin',
-  component: () => import(/* webpackChunkName: "main" */ '@/views/admin/Admin.vue')
-}]
+/**
+ * @deprecated 用户管理功能转移到单点登录
+ */
+
+// export default [{
+//   meta: { roles: ['admin'] },
+//   path: '/admin',
+//   name: 'admin',
+//   component: () => import(/* webpackChunkName: "main" */ '@/views/admin/Admin.vue')
+// }]
+
+export default []

+ 1 - 1
src/router/index.js

@@ -25,7 +25,7 @@ const routes = [
 ]
 
 const router = new VueRouter({
-  mode: 'hash',
+  mode: 'history',
   base: process.env.BASE_URL,
   routes
 })

+ 19 - 13
src/router/main.js

@@ -1,13 +1,19 @@
-export default [{
-  path: '/login',
-  name: 'login',
-  component: () => import(/* webpackChunkName: "main" */ '@/views/login/Login.vue')
-}, {
-  path: '/register',
-  name: 'register',
-  component: () => import(/* webpackChunkName: "main" */ '@/views/register/Register.vue')
-}, {
-  path: '/forget-password',
-  name: 'forget-password',
-  component: () => import(/* webpackChunkName: "main" */ '@/views/forget-password/ForgetPassword.vue')
-}]
+/**
+ * @deprecated 所有相关功能转移到单点登录
+ */
+
+// export default [{
+//   path: '/login',
+//   name: 'login',
+//   component: () => import(/* webpackChunkName: "main" */ '@/views/login/Login.vue')
+// }, {
+//   path: '/register',
+//   name: 'register',
+//   component: () => import(/* webpackChunkName: "main" */ '@/views/register/Register.vue')
+// }, {
+//   path: '/forget-password',
+//   name: 'forget-password',
+//   component: () => import(/* webpackChunkName: "main" */ '@/views/forget-password/ForgetPassword.vue')
+// }]
+
+export default []

+ 38 - 38
src/server/admin.js

@@ -1,38 +1,38 @@
-import axios from '@/plugins/axios'
-import { useAdminUrl } from '@/config/server-info'
-import generateSearchParams from '@/server/utils/generate-search-params'
-import userType from '@/enums/user-type'
-import { userState } from '@/enums/user-state'
-
-export function login ({ username, password }) {
-  return axios
-    .post(useAdminUrl('/login'), {
-      username,
-      password
-    })
-    .then(res => res.data)
-}
-
-// 获取注册教师列表
-export function getUsers ({ type = userType.teacher, state = userState.checking, key = '', page = 1, size = 10, sort = '' }) {
-  const params = generateSearchParams({ key, page, size, sort })
-  params.append('type', type)
-  params.append('state', state)
-  return axios.get(useAdminUrl('/user'), { params })
-    .then(res => res.data)
-}
-
-// 审核通过用户
-export function passUser ({ userId }) {
-  return axios.put(useAdminUrl(`/user/${userId}/pass`))
-}
-
-// 封禁用户
-export function lockUser ({ userId }) {
-  return axios.put(useAdminUrl(`/user/${userId}/lock`))
-}
-
-// 解封用户
-export function unlockUser ({ userId }) {
-  return axios.put(useAdminUrl(`/user/${userId}/unlock`))
-}
+// import axios from '@/plugins/axios'
+// import { useAdminUrl } from '@/config/server-info'
+// import generateSearchParams from '@/server/utils/generate-search-params'
+// import userType from '@/enums/user-type'
+// import { userState } from '@/enums/user-state'
+//
+// export function login ({ username, password }) {
+//   return axios
+//     .post(useAdminUrl('/login'), {
+//       username,
+//       password
+//     })
+//     .then(res => res.data)
+// }
+//
+// // 获取注册教师列表
+// export function getUsers ({ type = userType.teacher, state = userState.checking, key = '', page = 1, size = 10, sort = '' }) {
+//   const params = generateSearchParams({ key, page, size, sort })
+//   params.append('type', type)
+//   params.append('state', state)
+//   return axios.get(useAdminUrl('/user'), { params })
+//     .then(res => res.data)
+// }
+//
+// // 审核通过用户
+// export function passUser ({ userId }) {
+//   return axios.put(useAdminUrl(`/user/${userId}/pass`))
+// }
+//
+// // 封禁用户
+// export function lockUser ({ userId }) {
+//   return axios.put(useAdminUrl(`/user/${userId}/lock`))
+// }
+//
+// // 解封用户
+// export function unlockUser ({ userId }) {
+//   return axios.put(useAdminUrl(`/user/${userId}/unlock`))
+// }

+ 26 - 0
src/server/auth.js

@@ -0,0 +1,26 @@
+/**
+ * 统一认证登录相关接口
+ */
+
+const portal = 'http://p.seecoder.cn'
+
+export const getLoginUrl = () => {
+  const location = window.location
+  return `${portal}/api/interaction?client_id=seec-helper&redirect_uri=${encodeURIComponent(
+    location.origin + '/'
+  )}&scope=openid`
+}
+
+/**
+ * 跳转到登陆界面
+ */
+export const jumpToLogin = () => {
+  window.location.href = getLoginUrl()
+}
+
+/**
+ * 跳转到注册界面
+ */
+export const jumpToRegister = () => {
+  window.location.href = `${portal}/register`
+}

+ 59 - 59
src/server/user.js

@@ -2,65 +2,65 @@ import {
   useUserServer
 } from '@/config/server-info'
 import axios from '@/plugins/axios'
-import userType from '@/enums/user-type'
-
-// 注册,默认为注册学生账号
-export function register ({ name, email, emailCode, phone, phoneCode, password, type = userType.student }) {
-  const data = {
-    name,
-    email,
-    emailCode,
-    phone,
-    phoneCode,
-    password,
-    type
-  }
-  return axios
-    .post(useUserServer('/register'), data)
-    .then(res => res.data)
-}
-
-// 登录
-export function loginByEmail ({ email, password }) {
-  const data = {
-    username: email,
-    password
-  }
-
-  return axios
-    .post(useUserServer('/login/email'), data)
-    .then(res => res.data)
-}
-
-// 登出
-export function logout () {
-  return axios
-    .post(useUserServer('/logout'))
-    .then(res => {})
-}
-
-// 修改用户信息(目前只有姓名)
-export function modifyUser ({ name, type }) {
-  const data = {
-    name, type
-  }
-  return axios
-    .put(useUserServer(), data)
-    .then(res => res.data)
-}
-
-// 通过邮箱验证重设密码
-export function resetPasswordByEmail ({ email, code, password }) {
-  const data = {
-    username: email,
-    code,
-    password
-  }
-
-  return axios
-    .put(useUserServer('/resetPassword/email'), data)
-    .then(res => {})
-}
+// import userType from '@/enums/user-type'
+//
+// // 注册,默认为注册学生账号
+// export function register ({ name, email, emailCode, phone, phoneCode, password, type = userType.student }) {
+//   const data = {
+//     name,
+//     email,
+//     emailCode,
+//     phone,
+//     phoneCode,
+//     password,
+//     type
+//   }
+//   return axios
+//     .post(useUserServer('/register'), data)
+//     .then(res => res.data)
+// }
+//
+// // 登录
+// export function loginByEmail ({ email, password }) {
+//   const data = {
+//     username: email,
+//     password
+//   }
+//
+//   return axios
+//     .post(useUserServer('/login/email'), data)
+//     .then(res => res.data)
+// }
+//
+// // 登出
+// export function logout () {
+//   return axios
+//     .post(useUserServer('/logout'))
+//     .then(res => {})
+// }
+//
+// // 修改用户信息(目前只有姓名)
+// export function modifyUser ({ name, type }) {
+//   const data = {
+//     name, type
+//   }
+//   return axios
+//     .put(useUserServer(), data)
+//     .then(res => res.data)
+// }
+//
+// // 通过邮箱验证重设密码
+// export function resetPasswordByEmail ({ email, code, password }) {
+//   const data = {
+//     username: email,
+//     code,
+//     password
+//   }
+//
+//   return axios
+//     .put(useUserServer('/resetPassword/email'), data)
+//     .then(res => {})
+// }
 
 // 获取用户具体信息(可用于验证登录状态)
 export function getUserInfo () {

+ 12 - 5
src/store/modules/main.js

@@ -1,8 +1,8 @@
 import {
-  RESET_COURSE, RESET_COURSE_FILE_INFO,
+  RESET_COURSE, RESET_COURSE_FILE_INFO, RESET_TOKEN,
   RESET_USER_INFO,
   SET_COURSE,
-  SET_COURSE_FILE_INFO,
+  SET_COURSE_FILE_INFO, SET_TOKEN,
   SET_USER_INFO
 } from '@/store/types/main-types'
 
@@ -10,7 +10,8 @@ export default {
   state: {
     courseInfo: {},
     userInfo: {},
-    courseFileInfo: {}
+    courseFileInfo: {},
+    token: localStorage.getItem('token')
   },
 
   mutations: {
@@ -26,11 +27,17 @@ export default {
     [RESET_USER_INFO] (state) {
       state.userInfo = {}
     },
-    [SET_COURSE_FILE_INFO](state, payload) {
+    [SET_COURSE_FILE_INFO] (state, payload) {
       state.courseFileInfo = payload.courseFileInfo
     },
-    [RESET_COURSE_FILE_INFO](state) {
+    [RESET_COURSE_FILE_INFO] (state) {
       state.courseFileInfo = {}
+    },
+    [SET_TOKEN] (state, payload) {
+      state.token = payload.token
+    },
+    [RESET_TOKEN] (state) {
+      state.token = null
     }
   }
 }

+ 3 - 0
src/store/types/main-types.js

@@ -6,3 +6,6 @@ export const RESET_USER_INFO = 'resetUserInfo'
 
 export const SET_COURSE_FILE_INFO = 'setCourseFileInfo'
 export const RESET_COURSE_FILE_INFO = 'resetCourseFileInfo'
+
+export const SET_TOKEN = 'setToken'
+export const RESET_TOKEN = 'resetToken'

+ 14 - 8
src/views/Home.vue

@@ -4,24 +4,30 @@
       <h1 class="title">
         SEEC 课堂助手
       </h1>
-      <c-button @click="handleLogin" standout block theme="blue" class="mb-12">去登录</c-button>
-      <c-button block theme="blue" @click="handleRegister">去注册</c-button>
+      <!--      <c-button @click="handleLogin" standout block theme="blue" class="mb-12">去登录</c-button>-->
+      <!--      <c-button block theme="blue" @click="handleRegister">去注册</c-button>-->
+      <c-button icon="face" no-bold block theme="blue" standout @click="jumpToLogin">统一认证 - 登录</c-button>
+      <c-button icon="assignment_ind" block theme="green" class="mt-16" @click="jumpToRegister">统一认证 - 注册</c-button>
     </div>
   </div>
 </template>
 
 <script>
 import CButton from '@/components/Basic/CButton'
+import { jumpToLogin, jumpToRegister } from '@/server/auth'
 
 export default {
   components: { CButton },
   methods: {
-    handleLogin () {
-      this.$router.push({ name: 'login' })
-    },
-    handleRegister () {
-      this.$router.push({ name: 'register' })
-    }
+    // handleLogin () {
+    //   this.$router.push({ name: 'login' })
+    // },
+    // handleRegister () {
+    //   this.$router.push({ name: 'register' })
+    // }
+
+    jumpToLogin,
+    jumpToRegister
   }
 }
 </script>

+ 1 - 1
src/views/login/Login.vue

@@ -2,7 +2,7 @@
   <div class="login-view-container">
     <div>
       <h1 class="title"><span>SEEC</span>用户登录</h1>
-      <router-link :to="{name: userInfo.type === 'TEACHER' ? 'teacher' : 'student'}">
+      <router-link :to="{name: userInfo.role === 'TEACHER' ? 'teacher' : 'student'}">
         <c-button v-if="userInfo.name" block icon="face" theme="green" class="mb-16">已登录用户:{{userInfo.name}}</c-button>
       </router-link>
       <c-input class="mb-8" placeholder="邮箱" type="email" v-model="email"></c-input>

+ 18 - 0
src/views/login/ToRoleHomePage.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="no-content-warning">
+    正在跳转...
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style lang="scss" scoped>
+.no-content-warning {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100vh;
+}
+</style>

+ 6 - 3
src/views/shared/UserHomeLayout.vue

@@ -40,9 +40,10 @@
 
 <script>
 import IconButton from '@/components/Basic/IconButton'
-import { logout } from '@/server/user'
+// import { logout } from '@/server/user'
 import SlideInTransition from '@/animations/SlideInSameTransition'
 import CButton from '@/components/Basic/CButton'
+import { RESET_TOKEN, RESET_USER_INFO } from '@/store/types/main-types'
 
 export default {
   components: { CButton, IconButton, SlideInTransition },
@@ -79,9 +80,11 @@ export default {
       this.$router.push(`/${this.role}`)
     },
     handleLogout () {
-      logout()
+      // logout()
+      this.$store.commit(RESET_TOKEN)
+      this.$store.commit(RESET_USER_INFO)
       this.$setSuccessMessage('您已退出登录')
-      this.$router.push({ name: 'login' })
+      this.$router.push({ name: 'home' })
     }
   }
 }

+ 1 - 1
src/views/teacher/components/TeacherCourseDetail.vue

@@ -15,7 +15,7 @@
         <notice-card can-edit :notice="notice" :key="'notice-' + notice.id"></notice-card>
       </template>
     </template>
-    <div class="vertical-center">
+    <div class="vertical-center mt-24">
       <c-button icon="list" theme="blue" block @click="handleCheckSlideList">课件列表</c-button>
       <router-link :to="{ name: 'teacher-edit-notice', params: { noticeId: 0, courseId: course.id } }">
         <c-button theme="green" :left="12" icon="add">新建课程公告</c-button>

+ 1 - 0
vue.config.js

@@ -2,6 +2,7 @@ const webpack = require('webpack')
 
 module.exports = {
   devServer: {
+    port: 8000,
     proxy: {
       '^/api/question': {
         // target: 'http://localhost:4000',