vue微信授权登录后自动跳转原本要去的页面,顺便绑定上下级关系

2020-09-26  本文已影响0人  风中凌乱的男子

permission.js

import router from './router'
import store from './store'
import { switchVersion, getWxloginInfo } from '@/api/common'
import { getToken, getUrlParam, setToken, getPmemberId } from '@/utils/auth' // get token from cookie
const whiteList = ['/login', '/register', '/home', '/beautifulIndex', '/wxlogin'] // no redirect whitelist
store.dispatch('getLogo') //获取logp信息

router.beforeEach(async (to, from, next) => {

    // set page title
    // document.title = getPageTitle(to.meta.title)

    // determine whether the user has logged in
    const code = getUrlParam('code')
    const member_id = getUrlParam('member_id')
    const hasToken = getToken()
    if (hasToken) {
        if (to.path === '/login') {
            // if is logged in, redirect to the home page
            next({ path: '/' })
        } else {
            const hasGetUserInfo = store.getters.userInfo
            if (hasGetUserInfo) {
                next()
            } else {
                try {
                    // get user info
                    await store.dispatch('getUserInfo') // 请求获取用户信息

                    next({ ...to, replace: true })
                    // next()
                } catch (error) {
                    // remove token and go to login page to re-login
                    console.log(error);
                    await store.dispatch('resetToken')
                    // next(`/login?redirect=${to.path}`)
                    switchVersion().then(res => {
                        if (res.data == 1) {
                            next(`/login?redirect=${to.path}&member_id=${member_id}`)
                        }
                        if (res.data == 2) {
                            next(`/wxlogin?redirect=${to.path}&member_id=${member_id}`)
                        }
                    })
                }
            }
        }
    } else if (code) {
        // 获取用户信息和token
        await getWxloginInfo({ code: code, member_id: getPmemberId() }).then(res => {
            store.dispatch('setToken', res.data.info.token)
            setToken(res.data.info.token)
            store.dispatch('setUserInfo', res.data.info)
            if (process.env.NODE_ENV !== 'development' && router.mode === 'hash') {
                window.location.href = window.location.origin + window.location.pathname + window.location.hash
            } else {
                next()
            }
        })
    } else {
        /* has no token*/
        if (whiteList.indexOf(to.path) !== -1) {
            // in the free login whitelist, go directly
            next()
        } else {
            // 在未登录的情况下走这里,判断当前是哪种模式,跳转不同的登录页面
            switchVersion().then(res => {
                if (res.data == 1) {
                    next(`/login?redirect=${to.path}&member_id=${member_id}`)
                }
                if (res.data == 2) {
                    next(`/wxlogin?redirect=${to.path}&member_id=${member_id}`)
                }
            })
            // other pages that do not have permission to access are redirected to the login page.

        }

    }
})

auth.js

import Cookies from 'js-cookie'

const TokenKey = 'vue_erkzs_token'

const P_member_id = 'p_member_id'

const redirectKey = 'redirect'

export function getRedirectKey() {
    return Cookies.get(redirectKey)
}

export function setRedirectKey(redirect) {
    return Cookies.set(redirectKey, redirect)
}

export function removeRedirectKey() {
    return Cookies.remove(redirectKey)
}

export function getToken() {
    return Cookies.get(TokenKey)
}

export function setToken(token) {
    return Cookies.set(TokenKey, token)
}

export function removeToken() {
    return Cookies.remove(TokenKey)
}

export function setPmemberId(p_member_id) {
    return Cookies.set(P_member_id, p_member_id)
}

export function getPmemberId() {
    return Cookies.get(P_member_id)
}

export function removePemberId() {
    return Cookies.remove(P_member_id)
}

// export function getUrlParam(name) { //name为要获取的参数名
//     var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
//     var rrr = decodeURIComponent(window.location.search);
//     var r = rrr.substr(1).match(reg);
//     if (r != null) return unescape(r[2]);
//     return null;
// }

export function getUrlParam(name) {
    return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(window.location) || [, ""])[1].replace(/\+/g, '%20')) || null
}

wxLogin.vue

<template>
  <div>
  </div>
</template>

<script>
import { wxlogin } from "@/api/common";
import { getUrlParam, setPmemberId, setRedirectKey } from '@/utils/auth' // get token from cookie

export default {
  data() {
    return {
      redirect: undefined
    }
  },
  mounted() {
    const member_id = getUrlParam('member_id');
    setPmemberId(member_id);
    localStorage.setItem('login_type', 'wx')
    wxlogin().then(res => {
      window.location.href = res.data;
    });
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect
        setRedirectKey(this.redirect)
      },
      immediate: true
    },
  },
}
</script>

//放回调页面
//这里是检测到有重定向的path,就自动跳转过去  然后清除cookie中重定向的信息
  if (getRedirectKey() && localStorage.getItem('login_type') == 'wx') {
      this.$router.push({ path: getRedirectKey() })
      setTimeout(() => {
        removeRedirectKey()
      }, 100);
    } 

store vuex

import { getToken, setToken, removeToken, } from '@/utils/auth'
import { login, getSelfinfo, loginSms } from '@/api/user'
const state = {
    token: getToken(),
    userInfo: ''
}
const mutations = {
    SET_TOKEN: (state, token) => {
        state.token = token
    },
    SET_USER_INFO(state, userInfo) {
        state.userInfo = userInfo
    }
}
const actions = {
    //设置token
    setToken({ commit }, token) {
        commit('SET_TOKEN', token)
    },
    // 设置用户信息
    setUserInfo({ commit }, userInfo) {
        commit('SET_USER_INFO', userInfo)
    },
    // user login
    login({ commit }, userInfo) {
        const { loginame, password } = userInfo // 解构出用户名和密码
        return new Promise((resolve, reject) => {
            login({ loginame: loginame.trim(), password: password }).then(response => {
                commit("SET_TOKEN", response.token)
                setToken(response.token)
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },
    //phone login
    loginSms({ commit }, userInfo) {
        const { phone, code } = userInfo
        return new Promise((resolve, reject) => {
            loginSms({ phone: phone.trim(), code: code }).then(response => {
                commit("SET_TOKEN", response.token)
                setToken(response.token)
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },
    //getinfo 获取个人信息
    getUserInfo({ commit, state }) {
        return new Promise((resolve, reject) => {
            getSelfinfo().then(response => {
                // 获取到用户信息
                const userInfo = response.data
                commit("SET_USER_INFO", userInfo) // 触发vuex SET_NAME 保存名字到vuex
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },
    // remove token
    resetToken({ commit }) {
        return new Promise(resolve => {
            removeToken() // must remove  token  first
            resolve()
        })
    },

}
export default {
    state,
    mutations,
    actions
}

login.vue

<template>
  <div class="main">
    <div class="content">
      <!-- logo -->
      <div class="logo">
        <img src="http://pcsys.ybc365.com/8a896f6c-4d91-4622-b280-1f8e284ac8c3" alt="">
      </div>
      <!-- 手机号、验证码input  -->
      <div class="form" v-if='tabs == 1'>
        <section class="section">
          <input type="tel" maxlength="11" v-model="loginForm.phone" placeholder="手机号">
          <button class="CountButton" :disabled='disabled' @click="sendSms">
            {{codeMsg}}
          </button>
        </section>
        <section class="section">
          <input type="tel" maxlength="8" v-model="loginForm.code" placeholder="验证码">
        </section>
        <section class="MessageLogin">
          新用户登录即自动注册,并表示已同意
          <a href="#">《用户服务协议》</a>
          和
          <a href="#">《隐私权政策》</a>
        </section>
        <div class="btn">
          <van-button type="primary" block round color="#02b6fd" @click="handleLogin">登录</van-button>
        </div>
        <div class="type">
          <span @click="tabs = 2">密码登录</span>
          <!-- <span @click="$router.push('/register')">我要注册</span> -->
        </div>
        <span class="MessageLogin-31EIr">关于我们</span>
      </div>
      <!-- 用户名、密码input  -->
      <div class="form" v-if="tabs == 2">
        <section class="section">
          <input type="text" v-model="loginForm.phone" maxlength="20" placeholder="登录用户名">
        </section>
        <section class="section">
          <input type="password" maxlength="8" v-model="loginForm.password" placeholder="登录密码">
        </section>
        <section class="MessageLogin">
          新用户登录即自动注册,并表示已同意
          <a href="#">《用户服务协议》</a>
          和
          <a href="#">《隐私权政策》</a>
        </section>
        <div class="btn">
          <van-button type="primary" block round color="#02b6fd" style="height:40px;margin-bottom:20px;" @click="handleLogin">登录</van-button>
          <van-button type="primary" block round color="#02b6fd" style="height:40px;" @click="wxLogin">微信一键登录</van-button>
        </div>
        <div class="type">
          <span @click="tabs = 1">验证码登录</span>
          <!-- <span @click="$router.push('/register')">我要注册</span> -->
        </div>
        <span class="MessageLogin-31EIr">关于我们</span>
      </div>
    </div>
  </div>
</template>

<script>
import { login } from "@/api/user";
import { wxlogin } from "@/api/common";
import { getUrlParam, setPmemberId, setRedirectKey } from '@/utils/auth' // get token from cookie
export default {
  data() {
    return {
      tabs: 2,
      redirect: undefined,
      disabled: true,
      timer: null,
      codeMsg: "获取验证码",
      countdown: 60,
      loginForm: {
        phone: "",
        code: "",
        password: ""
      }
    }
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect
        setRedirectKey(this.redirect)
      },
      immediate: true
    },

    'loginForm.phone'(newVal, oldVal) {
      if (newVal.length == 11) {
        this.disabled = false
      } else {
        this.disabled = true
      }
    }
  },
  methods: {
    //登录请求
    handleLogin() {
      this.loading = true
      if (this.tabs == 1) {
        this.$store.dispatch('loginSms', this.loginForm).then(() => {
          this.$router.push({ path: this.redirect || '/' })
          this.loading = false
        }).catch(() => {
          this.loading = false
        })
      } else {
        this.$store.dispatch('login', this.loginForm).then(() => {
          this.$router.push({ path: this.redirect || '/' })
          this.loading = false
        }).catch(() => {
          this.loading = false
        })
      }
    },
    //发送短信
    sendSms() {
      if (!/^1[34578]\d{9}$/.test(this.loginForm.phone)) {
        this.$toast('请输入正确的手机号')
      } else {
        sendSms({ phone: this.loginForm.phone }).then(response => {
          this.$toast.success('发送成功')
          this.timer = setInterval(() => {
            this.countdown--
            if (this.countdown !== 0) {
              this.codeMsg = `重新发送${this.countdown}`
            } else {
              clearInterval(this.timer);
              this.codeMsg = "获取验证码";
              this.countdown = 60;
              this.timer = null;
              this.disabled = false;
            }
          }, 1000);
          this.disabled = true
        }).catch(err => {
          console.log(err);
        })
      }

    },
    wxLogin() {
      localStorage.setItem('login_type', 'wx')
      wxlogin().then(res => {
        window.location.href = res.data
      })
    }
  },
  mounted() {
    const member_id = getUrlParam('member_id');
    setPmemberId(member_id);
  },
}
</script>

<style lang="scss" scoped>
.main {
  padding: 0 37.5px;
  .content {
    padding-top: 10%;
    .logo {
      text-align: center;
      img {
        width: 139px;
      }
    }
    .form {
      margin-top: 30px;
      .section {
        position: relative;
        margin-bottom: 30px;
        height: 35px;
        font-size: 14px;
        background: #fff;
        input {
          width: 100%;
          height: 100%;
          left: 0;
          padding-left: 10px;
          border: 1px solid #ddd;
          border-radius: 4px;
          color: #333;
          -webkit-appearance: none;
          &::placeholder {
            color: #ccc;
          }
          &:focus {
            border: 1px solid #00acf0;
          }
        }
        .CountButton {
          border: none;
          padding: 0;
          color: #00acf0;
          background: transparent;
          text-align: center;
          font-size: 14px;
          display: inline-block;
          position: absolute;
          top: 50%;
          right: 10px;
          transform: translateY(-40%);
        }
        .CountButton[disabled] {
          color: #ccc;
        }
      }
      .MessageLogin {
        margin-top: 12px;
        color: #999;
        font-size: 13px;
        line-height: 22px;
        a {
          color: #00acf0;
        }
      }
      .btn {
        margin-top: 30px;
      }
      .type {
        display: flex;
        justify-content: space-between;
        line-height: 50px;
        color: #999;
        padding: 0 10px;
        font-size: 12px;
      }
      .MessageLogin-31EIr {
        color: #999;
        position: absolute;
        bottom: 3%;
        left: 50%;
        margin-left: -20px;
      }
    }
  }
}
</style>

request.js

import axios from 'axios'
import store from '@/store'
import router from '../router'
import { Toast } from 'vant'
// 根据环境不同引入不同api地址
import { baseApi } from '@/config'
import { getToken, getUrlParam } from '@/utils/auth'
import { switchVersion } from '@/api/common'

// create an axios instance
const service = axios.create({
    baseURL: baseApi, // url = base api url + request url
    withCredentials: true, // send cookies when cross-domain requests
    timeout: 5000 // request timeout
})
const member_id = getUrlParam('member_id')
setPmemberId(member_id)
// request拦截器 request interceptor
service.interceptors.request.use(
    config => {
        // 不传递默认开启loading
        if (!config.hideloading) {
            // loading
            Toast.loading({
                forbidClick: true
            })
        }
        if (store.getters.token) {
            config.headers['token'] = getToken()
        }
        return config
    },
    error => {
        // do something with request error
        console.log(error) // for debug
        return Promise.reject(error)
    }
)
// respone拦截器
service.interceptors.response.use(
    response => {
        Toast.clear()
        const res = response.data
        if (res.code && res.code != 200) {
            if (res.code == 1) {
                return Promise.resolve(res)
            } else if (res.code == -4 || res.code == -2) {
                Toast.fail(res.msg || '请求出错')
            } else {
                Toast.fail(res.message || '请求出错')
            }
            // 登录超时,重新登录
            if (res.code == 401) {
                // store.dispatch('FedLogOut').then(() => {
                // location.reload()
                // })
            }
            return Promise.reject(res || 'error')
        } else {
            return Promise.resolve(res)
        }
    },
    error => {
        Toast.clear()
        //捕获401
        store.dispatch('resetToken')
        localStorage.removeItem('login_type')
        switchVersion().then(res => {
            if (res.data == 1) {
                router.replace(`/login?redirect=/${(window.location.hash).split('/')[1]}`)
            }
            if (res.data == 2) {
                router.replace({
                    path: `/wxlogin?redirect=/${(window.location.hash).split('/')[1]}`
                })
            }
        })
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)

export default service
上一篇 下一篇

猜你喜欢

热点阅读