yoho-plugin-auth.js 3.61 KB
/**
 * 权限插件
 */
import _ from 'lodash';
import axios from 'axios';
import UserService from 'services/user/user-service';
import crypto from 'util/crypto';

export default {
  updateUser(Vue, user, purviews) {
    Vue.$store.set(Vue.$config.storeKeys.user, crypto.aesEncrypt(user));
    Vue.prop('purviews', purviews.deep);
    Vue.prop('oriPurviews', purviews.ori);
    Vue.prop('user', user);
    Vue.prop('isLogin', true);
  },

  // 权限验证
  checkPurview() {
    return Promise.resolve();

    // let pur = _.find(Vue.$purviews, p => p.menu_url === to.path);

    // if (pur) {
    //     return Promise.resolve();
    // }
    // return Promise.reject();
  },
  initPurview(Vue, user) {
    return this.userService.purviews().then(purviews => {
      this.updateUser(Vue, user, purviews);
    });
  },
  initConfig(Vue) {
    return this.userService.config().then(data => {
      Object.assign(Vue.$config, data);
      Vue.prop('config', Vue.$config);
    });
  },
  install(Vue) {
    this.userService = new UserService();

    Vue.beforeRender(next => {
      let user = Vue.$store.get(Vue.$config.storeKeys.user);
      const isLogin = Vue.$cookie.get('_isLogin');

      if (isLogin && user) {
        try {
          user = crypto.aesDecrypt(user, Object);
          return Promise.all([this.initPurview(Vue, user), this.initConfig(Vue)]).then(
            () => {
              next();
            },
            () => {
              next();
            }
          );
        } catch (e) {
          Vue.logout();
        }
      }
      next();
    });

    // 路由权限控制
    Vue.$router.beforeEach((to, from, next) => {
      // 需要修改密码去修改密码
      if (Vue.$store.get('needUpdate') && to.name !== 'login' && to.name !== 'user.password') {
        return next('/user/password.html');
      }

      // 无权限控制理由直接pass
      const authPass = _.get(_.last(to.matched), 'meta.authPass', false);

      if (authPass) {
        // 已登录跳转到首页
        if (to.name === 'login' && Vue.$isLogin) {
          return next('/');
        }
        return next();
      }

      // 未登录去登录
      if (!Vue.$isLogin) {
        return next('/login.html');
      }
      return this.checkPurview(Vue, to).then(
        () => {
          return next();
        },
        () => {
          return next('/401.html');
        }
      );
    });

    Vue.passport = {
      local: (username, password, captcha) => {
        return this.userService.login(username, password, captcha).then(res => {
          if (res.code === 200) {
            return Promise.all([this.initPurview(Vue, res.data), this.initConfig(Vue)]).then(() => {
              if (res.data.needUpdate) {
                Vue.$store.set('needUpdate', true);
              }
              return res.data;
            });
          }
          return Promise.reject(res);
        });
      },
    };
    Vue.switchShop = shopsId => {
      Vue.$store.set(Vue.$config.storeKeys.user, crypto.aesEncrypt(Vue.$user));
      Vue.$cookie.set('_sign', shopsId, {
        path: '/',
      });
    };
    Vue.logout = () => {
      _.each(Vue.$config.storeKeys, Vue.$store.remove);
      Vue.prop('user', void 0);
      Vue.prop('isLogin', void 0);
      Vue.prop('purviews', void 0);
      Vue.$store.remove('needUpdate');
      axios.post('/logout');
      Vue.$router.push('/login.html');
    };
    axios.defaults.validateStatus = status => {
      if (status === 401) {
        Vue.logout();
        return false;
      }
      if (status === 403) {
        Vue.$store.set('needUpdate', true);
        return false;
      }
      return true;
    };
  },
};