yoho-plugin-auth.js 4.38 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);
            let 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
            let 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;
        };
    }
};