Browse Source

添加登录页面

lsc 5 months ago
parent
commit
17c6bdcd78

+ 4 - 0
.env.development

@@ -0,0 +1,4 @@
+NODE_ENV='development'
+# must start with VUE_APP_ 
+VUE_APP_ENV = 'development'
+ 

+ 4 - 0
.env.production

@@ -0,0 +1,4 @@
+NODE_ENV='production'
+# must start with VUE_APP_
+VUE_APP_ENV = 'production'
+ 

+ 4 - 0
.env.staging

@@ -0,0 +1,4 @@
+NODE_ENV='production'
+# must start with VUE_APP_
+VUE_APP_ENV = 'staging'
+ 

+ 25 - 0
package-lock.json

@@ -11,6 +11,8 @@
         "axios": "^1.7.9",
         "core-js": "^3.8.3",
         "element-ui": "^2.15.14",
+        "js-cookie": "^3.0.5",
+        "nprogress": "^0.2.0",
         "vue": "^2.6.14",
         "vue-router": "^3.6.5",
         "vuex": "^3.6.2"
@@ -6870,6 +6872,14 @@
         "@sideway/pinpoint": "^2.0.0"
       }
     },
+    "node_modules/js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+      "engines": {
+        "node": ">=14"
+      }
+    },
     "node_modules/js-message": {
       "version": "1.0.7",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
@@ -7792,6 +7802,11 @@
         "node": ">=4"
       }
     },
+    "node_modules/nprogress": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
+      "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
+    },
     "node_modules/nth-check": {
       "version": "2.1.1",
       "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz",
@@ -16388,6 +16403,11 @@
         "@sideway/pinpoint": "^2.0.0"
       }
     },
+    "js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="
+    },
     "js-message": {
       "version": "1.0.7",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
@@ -17105,6 +17125,11 @@
         "path-key": "^2.0.0"
       }
     },
+    "nprogress": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
+      "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
+    },
     "nth-check": {
       "version": "2.1.1",
       "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz",

+ 2 - 0
package.json

@@ -11,6 +11,8 @@
     "axios": "^1.7.9",
     "core-js": "^3.8.3",
     "element-ui": "^2.15.14",
+    "js-cookie": "^3.0.5",
+    "nprogress": "^0.2.0",
     "vue": "^2.6.14",
     "vue-router": "^3.6.5",
     "vuex": "^3.6.2"

+ 49 - 0
src/api/user.js

@@ -0,0 +1,49 @@
+// axios
+import axios from '@/common/axios.config'
+import { baseApi } from '@/config'
+
+// 用户信息 post 方法
+export function eduGet() {
+  return axios.get('//beta.api.cocorobo.cn/api/getcookieuserid')
+}
+export function eduGetUserinfo(rk) {
+  return axios.get(`//api.edu.cocorobo.cn/edu/admin/userinfo/userinfoById/${rk}`)
+}
+
+// 退出登录
+export function loginOut(data) {
+  return axios.post('//beta.api.cocorobo.cn/api/logout',data)
+}
+
+export function getUser(data) {
+  return axios.get(`${baseApi}/selectUser`, data)
+}
+
+// // 登录
+// export function login(data) {
+//   return request({
+//     url: api.Login,
+//     method: 'post',
+//     data
+//   })
+// }
+
+// // 用户信息 post 方法
+// export function getUserInfo(data) {
+//   return request({
+//     url: api.UserInfo,
+//     method: 'post',
+//     data,
+//     hideloading: true
+//   })
+// }
+
+// // 用户名称 get 方法
+// export function getUserName(params) {
+//   return request({
+//     url: api.UserName,
+//     method: 'get',
+//     params,
+//     hideloading: true
+//   })
+// }

+ 12 - 0
src/config/env.development.js

@@ -0,0 +1,12 @@
+// 本地环境配置
+module.exports = {
+  env: 'development',
+  title: 'cocorobo', // 代理端-开发
+  baseUrl: 'http://localhost:9018', // 项目地址
+  baseApi: 'https://pbl.cocorobo.cn/api/pbl/', // 本地api请求地址,注意:如果你使用了代理,请设置成'/'
+  // baseApi: '/', // 本地api请求地址,注意:如果你使用了代理,请设置成'/'
+  // baseApi: 'http://localhost:7003/api/pbl/', // 本地api请求地址,注意:如果你使用了代理,请设置成'/'
+  APPID: 'xxx',
+  APPSECRET: 'xxx',
+  $cdn: 'https://imgs.solui.cn'
+}

+ 10 - 0
src/config/env.production.js

@@ -0,0 +1,10 @@
+// 正式
+module.exports = {
+  env: 'production',
+  title: 'cocorobo', // 代理端-生产
+  baseUrl: 'https://www.xxx.com/', // 正式项目地址
+  baseApi: 'https://pbl.cocorobo.cn/api/pbl/', // 正式api请求地址
+  APPID: 'xxx',
+  APPSECRET: 'xxx',
+  $cdn: 'https://imgs.solui.cn'
+}

+ 9 - 0
src/config/env.staging.js

@@ -0,0 +1,9 @@
+module.exports = {
+  env: 'staging',
+  title: 'cocorobo', // 代理端-测试
+  baseUrl: 'https://test.xxx.com', // 测试项目地址
+  baseApi: 'https://test.xxx.com/api', // 测试api请求地址
+  APPID: 'xxx',
+  APPSECRET: 'xxx',
+  $cdn: 'https://imgs.solui.cn'
+}

+ 6 - 0
src/config/index.js

@@ -0,0 +1,6 @@
+// 根据环境引入不同配置 process.env.NODE_ENV
+// debugger
+// console.log(process.env);
+
+const config = require('./env.' + process.env.VUE_APP_ENV)
+module.exports = config

+ 1 - 0
src/main.js

@@ -7,6 +7,7 @@ import ElementUI from 'element-ui'; // 引入 Element UI
 import 'element-ui/lib/theme-chalk/index.css'; // 引入 Element UI 样式
 
 import axios from './common/axios.config'; // 引入 axios 配置实例
+import '@/permission' // permission control
 
 Vue.config.productionTip = false; // 关闭生产模式提示
 

+ 66 - 0
src/permission.js

@@ -0,0 +1,66 @@
+import router from './router'
+import store from './store'
+import NProgress from 'nprogress' // progress bar
+import 'nprogress/nprogress.css' // progress bar style
+// import { getToken } from '@/utils/auth' // get token from cookie
+
+NProgress.configure({ showSpinner: false }) // NProgress Configuration
+
+const whiteList = ['/login',] // no redirect whitelist
+
+router.beforeEach(async(to, from, next) => {
+  // start progress bar
+  NProgress.start()
+  // set page title
+
+  // determine whether the user has logged in
+  // const hasToken = getToken()
+  const hasToken = store.getters.token
+
+  if (hasToken) {
+    if (to.path === '/login') {
+      // if is logged in, redirect to the home page
+
+      next({ path: '/' })
+      NProgress.done()
+    } else {
+      const userinfo = store.getters.userinfo && Object.keys(store.getters.userinfo).length > 0
+      console.log('store.getters', store.getters)
+      console.log('userinfo', userinfo)
+      // console.log('to', {...to} )
+      if (userinfo) {
+        next()
+      } else {
+        try {
+          // 获取用户信息
+          const data = await store.dispatch('user/getInfo')
+          await store.commit('user/SET_USERINFO', data)
+
+          next({ ...to, replace: true })
+        } catch (error) {
+          // remove token and go to login page to re-login
+          // await store.dispatch('user/resetToken')
+          // Notify({ type: 'danger', message: error || '发生异常' })
+          next(`/login?redirect=${to.path}`)
+          NProgress.done()
+        }
+      }
+    }
+  } else {
+    // next()
+    /* 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()
+    }
+  }
+})
+
+router.afterEach(() => {
+  // finish progress bar
+  NProgress.done()
+})

+ 8 - 0
src/router/index.js

@@ -7,6 +7,14 @@ import UserExamine from '@/components/examine.vue'; // 账号审核组件
 Vue.use(VueRouter);
 
 const routes = [
+  {
+    path: '/login',
+    component: () => import('@/views/login/index'),
+    meta: {
+      title: '登录',
+      keepAlive: false
+    }
+  },
   {
     path: '/',
     name: 'home',

+ 9 - 0
src/store/getters.js

@@ -0,0 +1,9 @@
+const getters = {
+  courseId: state => state.app.courseId,
+  testId: state => state.app.testId,
+  shareCourseId: state => state.app.shareCourseId,
+  id: state => state.user.id,
+  userinfo: state => state.user.userinfo,
+  token: state => state.user.token,
+}
+export default getters

+ 10 - 10
src/store/index.js

@@ -1,17 +1,17 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
+import getters from './getters'
+import app from './modules/app'
+import user from './modules/user'
 
 Vue.use(Vuex)
 
-export default new Vuex.Store({
-  state: {
-  },
-  getters: {
-  },
-  mutations: {
-  },
-  actions: {
-  },
+const store = new Vuex.Store({
   modules: {
-  }
+    app,
+    user
+  },
+  getters
 })
+
+export default store

+ 22 - 0
src/store/modules/app.js

@@ -0,0 +1,22 @@
+const state = {
+  courseId: '',
+  testId: '',
+  shareCourseId: ''
+}
+const mutations = {
+  SET_COURSEID: (state, courseId) => {
+    state.courseId = courseId
+  },
+  SET_TESTID: (state, courseId) => {
+    state.testId = courseId
+  },
+  SET_SHARECOURSEID: (state, courseId) => {
+    state.shareCourseId = courseId
+  }
+}
+const actions = {}
+export default {
+  state,
+  mutations,
+  actions
+}

+ 151 - 0
src/store/modules/user.js

@@ -0,0 +1,151 @@
+// import { user_info, login } from '@/api/user'
+import { eduGet, getUser } from "@/api/user";
+import { getToken, removeToken, setToken } from "@/utils/auth";
+const getDefaultState = () => {
+  return {
+    token: getToken(),
+    id: "",
+    roles: [],
+    name: "",
+    username: "",
+    avatar: "",
+    is_init: false,
+    userinfo: "",
+  };
+};
+
+const state = getDefaultState();
+const mutations = {
+  RESET_STATE: (state) => {
+    Object.assign(state, getDefaultState());
+  },
+  SET_TOKEN: (state, token) => {
+    state.token = token;
+  },
+  SET_ROLES: (state, roles) => {
+    state.roles = roles;
+  },
+  SET_ID: (state, id) => {
+    state.id = id;
+  },
+  SET_NAME: (state, name) => {
+    state.name = name;
+  },
+  SET_USERNAME: (state, name) => {
+    state.username = name;
+  },
+  SET_IS_INIT: (state, is_init) => {
+    state.is_init = is_init;
+  },
+  SET_AVATAR: (state, avatar) => {
+    state.avatar = avatar;
+  },
+  SET_USERINFO: (state, userinfo) => {
+    state.userinfo = userinfo;
+  },
+};
+
+const actions = {
+  login({ commit }) {
+    return new Promise((resolve, reject) => {
+      eduGet()
+        .then((response) => {
+          console.log(response);
+          var _user = response.data[0][0];
+          commit("SET_ID", _user.userid);
+          setToken(_user.userid);
+          // dispatch('getInfo')
+          resolve(_user.userid);
+        })
+        .catch((error) => {
+          // var _user = { userid: "6c56ec0e-2c74-11ef-bee5-005056b86db5" };
+          // commit("SET_ID", _user.userid);
+          // setToken(_user.userid);
+          // resolve(_user.userid);
+          reject(error);
+        });
+    });
+  },
+  getInfo({ commit, state }) {
+    return new Promise((resolve, reject) => {
+      debugger;
+      // getToken()
+      commit("SET_ID", state.token);
+
+      getUser({ userid: state.token })
+        .then((response) => {
+          console.log(response);
+          // const { data } = response
+          const data = response.data[0][0];
+          if (!data) {
+            reject("验证失败,请重新登录。");
+          }
+          // console.log(response)
+          commit("SET_USERINFO", data);
+          resolve(data);
+          // resolve()
+        })
+        .catch((error) => {
+          reject(error);
+        });
+    });
+  },
+  // get user info
+  // getInfo({ commit, state }) {
+  //   return new Promise((resolve, reject) => {
+  //     getUser()
+  //       .then(response => {
+  //         const { data } = response
+
+  //         if (!data) {
+  //           reject('验证失败,请重新登录。')
+  //         }
+  //         console.log(response)
+
+  //         const { id, roles, is_init, cn, avatar, username } = response.data
+  //         // roles must be a non-empty array
+  //         if (!roles || roles.length <= 0) {
+  //           reject('getInfo: 角色必须为非空数组!')
+  //         }
+  //         commit('SET_NAME', cn)
+  //         commit('SET_USERNAME', username)
+  //         commit('SET_ROLES', roles)
+  //         commit('SET_ID', id)
+  //         commit('SET_AVATAR', avatar)
+  //         commit('SET_IS_INIT', is_init)
+  //         resolve(data)
+  //       })
+  //       .catch(error => {
+  //         reject(error)
+  //       })
+  //   })
+  // },
+
+  // user logout
+  logout({ commit }) {
+    return new Promise((resolve) => {
+      commit("SET_TOKEN", "");
+      commit("SET_ROLES", []);
+      removeToken();
+      commit("RESET_STATE");
+      resolve();
+    });
+  },
+
+  // remove token
+  resetToken({ commit }) {
+    return new Promise((resolve) => {
+      commit("SET_TOKEN", "");
+      commit("SET_ROLES", []);
+      removeToken();
+      resolve();
+    });
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 15 - 0
src/utils/auth.js

@@ -0,0 +1,15 @@
+import Cookies from 'js-cookie'
+
+const TokenKey = 'vue_admin_template_token'
+
+export function getToken() {
+  return Cookies.get(TokenKey)
+}
+
+export function setToken(token) {
+  return Cookies.set(TokenKey, token)
+}
+
+export function removeToken() {
+  return Cookies.remove(TokenKey)
+}

+ 69 - 0
src/views/login/index.vue

@@ -0,0 +1,69 @@
+<template>
+  <div class="loginBox">
+    <iframe src="//edu.cocorobo.cn/course/login?type=2" frameborder="0"></iframe>
+    <!-- <button @click="handleLogin">登录</button> -->
+  </div>
+</template>
+
+<script>
+import { mapActions } from 'vuex'
+export default {
+  name: 'LoginPage',
+  data() {
+    return {
+      redirect: undefined,
+      timer: null
+    }
+  },
+  watch: {
+    $route: {
+      handler: function(route) {
+        this.redirect = route.query && route.query.redirect
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    ...mapActions({
+      login: 'user/login'
+    }),
+    handleLogin() {
+      this.$router.push({ path: this.redirect || '/' })
+    },
+    async getLogin() {
+
+      const userid = await this.login()
+      if (userid) {
+        this.$router.push({ path: this.redirect || '/' })
+      }
+      // eduGet().then(res => {})
+    }
+  },
+  beforeDestroy() {
+    clearInterval(this.timer)
+    this.timer = null
+  },
+  mounted() {
+    this.getLogin()
+    this.timer = setInterval(() => {
+      this.getLogin()
+    }, 2000)
+  }
+}
+</script>
+
+<style  scoped>
+.loginBox {
+  position: relative;
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+
+}
+
+.loginBox > iframe {
+  width: 100%;
+  height: 100%;
+  border: 0;
+}
+</style>