登录完成
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
"dingtalk-jsapi": "^3.0.20",
|
"dingtalk-jsapi": "^3.0.20",
|
||||||
"echarts": "5.2.2",
|
"echarts": "5.2.2",
|
||||||
"element-ui": "2.15.6",
|
"element-ui": "2.15.6",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"screenfull": "5.2.0",
|
"screenfull": "5.2.0",
|
||||||
"serve": "^14.2.0",
|
"serve": "^14.2.0",
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import setIntroduction from "@/utils/setIconfont.js";
|
|||||||
import { Local } from "@/utils/storage.js";
|
import { Local } from "@/utils/storage.js";
|
||||||
import Setings from "@/layout/navBars/breadcrumb/setings.vue";
|
import Setings from "@/layout/navBars/breadcrumb/setings.vue";
|
||||||
import Upgrade from "@/layout/upgrade/index.vue";
|
import Upgrade from "@/layout/upgrade/index.vue";
|
||||||
|
import jsonwebtoken from 'jsonwebtoken'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
components: { Setings, Upgrade },
|
components: { Setings, Upgrade },
|
||||||
@@ -17,6 +19,10 @@ export default {
|
|||||||
this.initSetIconfont();
|
this.initSetIconfont();
|
||||||
this.openSetingsDrawer();
|
this.openSetingsDrawer();
|
||||||
this.getLayoutThemeConfig();
|
this.getLayoutThemeConfig();
|
||||||
|
console.log('jsonwebtoken')
|
||||||
|
const token = 'eyJ4NXQjUzI1NiI6IkRIS0NvOTNWbURZd0tRNk5xX3BEOFdnNDUtRTBzQ2h6c3VKNThjbmVzeDAiLCJraWQiOiJkc3dqIiwiYWxnIjoiUlMyNTYifQ.eyJjYW1wdXNJbmZvIjpbeyJjYW1wdXNJZCI6ODUxNDY2OTMyLCJjYW1wdXNOYW1lIjoi6IOW6IOW5pWZ6IKy6ZuG5ZuiIiwiY2xhc3NJbmZvIjpbeyJjbGFzc0lkIjo4NTEzODI3ODYsImNsYXNzTmFtZSI6IuWkp-ePrTHnj60iLCJjbGFzc1JvbGVMaXN0IjpbeyJyb2xlIjoiZ3VhcmRpYW4iLCJpc0FkdmlzZXIiOjB9LHsicm9sZSI6InRlYWNoZXIiLCJpc0FkdmlzZXIiOjB9XX1dfV0sInN1YiI6IuW8oOS4iSIsImlzcyI6Imh0dHA6Ly9hdXRoLmNwb2xhci5jbiIsInVzZXJpZCI6IjIxMzE1ODQ2MzkzMjMxNjkwMSIsImF1dGhvcml0aWVzIjpbInVzZXIucmVhZCIsInRlc3QiLCJ1c2VyX2luZm8iLCJvcGVuaWQiLCJwcm9maWxlIiwiU0NPUEVfdGVzdCIsIlNDT1BFX3Rlc3QucmVhZCJdLCJhdWQiOiJ0ZXN0LWNsaWVudCIsIm5iZiI6MTcxMDEyOTA5NSwicm9sZUluZm8iOlt7InJvbGVJZCI6Mzc1OTk0NzEzMiwicm9sZU5hbWUiOiLkuLvnrqHnkIblkZgiLCJhdXRob3JpdGllcyI6WyJTQ09QRV90ZXN0IiwiU0NPUEVfdGVzdC5yZWFkIl19LHsicm9sZUlkIjozNzU5OTQ3MTM1LCJyb2xlTmFtZSI6IuS4u-euoSIsImF1dGhvcml0aWVzIjpbXX0seyJyb2xlSWQiOjM3NTk5NDcxMzcsInJvbGVOYW1lIjoi5Zut6ZW_IiwiYXV0aG9yaXRpZXMiOltdfSx7InJvbGVJZCI6Mzc3MjEyODMzNSwicm9sZU5hbWUiOiJ0ZXN0IiwiYXV0aG9yaXRpZXMiOltdfV0sInNjb3BlIjpbInVzZXIucmVhZCIsInRlc3QiLCJ1c2VyX2luZm8iLCJvcGVuaWQiLCJwcm9maWxlIl0sImV4cCI6MTcxMDIxNTQ5NSwiZGVwdEluZm8iOltdLCJpYXQiOjE3MTAxMjkwOTV9.LCMTCclfbhVJVzU1EjdrY7gpR7W7VKzt3-9nwTcZjv2A1bCigmUQjRI6S8dMMF_mIfptiUer5nCk1CBAYm-xQ-Rj86bOf1fqseg6UDTM1_ehiSYR5OSYHcbTMSxvA9RtaA05kT9kReCpUyMeAgdV4-Uj453cTEiGlTrK2TXNthosgIcwgRZooNcMEGGsV-YMkYv69Nmv9e9F8d2lQ26w8MZ-Rke5BUL2fvsvy-XBW8ygvkcarUWfdwml9XDXSLRK1sRCSad1ghvR84EkS8qK_Ii5LoKaxuZ7j4OSJifGeWNuTYveaTTtUy9ZG7cCbD7-kSdOxpgeNS0MjZDc22Xdhg'
|
||||||
|
console.log(jsonwebtoken.decode(token))
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 设置初始化,防止刷新时恢复默认
|
// 设置初始化,防止刷新时恢复默认
|
||||||
|
|||||||
@@ -15,3 +15,56 @@ export function formatDate (timeStr = (new Date()), separator = '-', type){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
重置表单对象
|
||||||
|
@param { Object } form(必填) 需要重置的表单
|
||||||
|
@param { Object } rules(选填) 指定需要重置的值默认设为null 试例rules:{ name: 1 } name字段重置为1
|
||||||
|
@return { Object } 重置后的值
|
||||||
|
*/
|
||||||
|
export function resetForm(form, rules = {}) {
|
||||||
|
for (let key in form) {
|
||||||
|
if (checkType(form[key]) == "Array") {
|
||||||
|
if (rules.hasOwnProperty(key)) {
|
||||||
|
// 是否包含需要更改的
|
||||||
|
form[key] = rules[key];
|
||||||
|
} else {
|
||||||
|
form[key] = [];
|
||||||
|
}
|
||||||
|
} else if (checkType(form[key]) == "Object") {
|
||||||
|
if (rules.hasOwnProperty(key)) {
|
||||||
|
// 是否包含需要更改的
|
||||||
|
form[key] = rules[key];
|
||||||
|
} else {
|
||||||
|
form[key] = {};
|
||||||
|
}
|
||||||
|
} else if (checkType(form[key]) == "Boolean") {
|
||||||
|
if (rules.hasOwnProperty(key)) {
|
||||||
|
// 是否包含需要更改的
|
||||||
|
form[key] = rules[key];
|
||||||
|
} else {
|
||||||
|
form[key] = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rules.hasOwnProperty(key)) {
|
||||||
|
// 是否包含需要更改的
|
||||||
|
form[key] = rules[key];
|
||||||
|
} else {
|
||||||
|
form[key] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 手机号验证
|
||||||
|
@param { Number } IdcardVal(必填) 手机号
|
||||||
|
@return { Boolean } true 通过 false 失败
|
||||||
|
*/
|
||||||
|
export function rulesPhone(phoneVal) {
|
||||||
|
let phoneReg = /(^1\d{10}$)|(^[0-9]\d{7}$)/;
|
||||||
|
if (!phoneReg.test(phoneVal)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// 定义内容
|
// 定义内容
|
||||||
export default {
|
export default {
|
||||||
login: {
|
login: {
|
||||||
placeholder1: 'The user name admin or not is test',
|
placeholder1: 'Please enter your phone number',
|
||||||
placeholder2: 'Password: 123456',
|
placeholder2: 'Please enter the verification code',
|
||||||
placeholder3: 'Please enter the verification code',
|
placeholder3: 'Please enter the verification code',
|
||||||
btnText: 'Sign in',
|
btnText: 'Sign in',
|
||||||
link: {
|
link: {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// 定义内容
|
// 定义内容
|
||||||
export default {
|
export default {
|
||||||
login: {
|
login: {
|
||||||
placeholder1: '用户名 admin 或不输均为 test',
|
placeholder1: '请输入手机号',
|
||||||
placeholder2: '密码:123456',
|
placeholder2: '请输入验证码',
|
||||||
placeholder3: '请输入验证码',
|
placeholder3: '请输入验证码',
|
||||||
btnText: '登 录',
|
btnText: '登 录',
|
||||||
link: {
|
link: {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// 定义内容
|
// 定义内容
|
||||||
export default {
|
export default {
|
||||||
login: {
|
login: {
|
||||||
placeholder1: '用戶名admin或不輸均為test',
|
placeholder1: '請輸入驗證碼',
|
||||||
placeholder2: '密碼:123456',
|
placeholder2: '請輸入驗證碼',
|
||||||
placeholder3: '請輸入驗證碼',
|
placeholder3: '請輸入驗證碼',
|
||||||
btnText: '登 录',
|
btnText: '登 录',
|
||||||
link: {
|
link: {
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import store from '../store';
|
||||||
|
import VueRouter from 'vue-router';
|
||||||
|
import NProgress from 'nprogress';
|
||||||
|
import 'nprogress/nprogress.css';
|
||||||
|
import { Session } from '@/utils/storage';
|
||||||
|
import { PrevLoading } from '@/utils/loading.js';
|
||||||
|
import { useMenuApi } from '@/api/menu';
|
||||||
|
import adminbendirout from '../../public/admin';
|
||||||
|
|
||||||
|
const menuApi = useMenuApi();
|
||||||
|
|
||||||
|
// 解决 `element ui` 导航栏重复点菜单报错问题
|
||||||
|
const originalPush = VueRouter.prototype.push;
|
||||||
|
VueRouter.prototype.push = function push(location) {
|
||||||
|
return originalPush.call(this, location).catch((err) => err);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 安装 VueRouter 插件
|
||||||
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
|
// 定义动态路由
|
||||||
|
const dynamicRoutes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: '/',
|
||||||
|
component: 'layout/index',
|
||||||
|
redirect: '/home',
|
||||||
|
meta: {
|
||||||
|
isKeepAlive: true,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 定义静态路由
|
||||||
|
const staticRoutes = [
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'login',
|
||||||
|
component: () => import('@/views/login'),
|
||||||
|
meta: {
|
||||||
|
title: '登录',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/404',
|
||||||
|
name: 'notFound',
|
||||||
|
component: () => import('@/views/error/404.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.staticRoutes.notFound',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/401',
|
||||||
|
name: 'noPower',
|
||||||
|
component: () => import('@/views/error/401.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.staticRoutes.noPower',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 加载静态路由
|
||||||
|
const createRouter = () =>
|
||||||
|
new VueRouter({
|
||||||
|
routes: staticRoutes,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 创建路由
|
||||||
|
const router = createRouter();
|
||||||
|
|
||||||
|
// 加载 loading
|
||||||
|
PrevLoading.start();
|
||||||
|
|
||||||
|
// 多级嵌套数组处理成一维数组
|
||||||
|
export function formatFlatteningRoutes(arr) {
|
||||||
|
if (arr.length <= 0) return false;
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (arr[i].children) {
|
||||||
|
arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理 tagsViewList 数据,默认路由全部缓存
|
||||||
|
// isKeepAlive 处理 `name` 值,进行路由缓存
|
||||||
|
export function formatTwoStageRoutes(arr) {
|
||||||
|
if (arr.length <= 0) return false;
|
||||||
|
const newArr = [];
|
||||||
|
const cacheList = [];
|
||||||
|
arr.forEach((v) => {
|
||||||
|
newArr.push({ ...v });
|
||||||
|
cacheList.push(v.name);
|
||||||
|
store.dispatch('keepAliveNames/setCacheKeepAlive', cacheList);
|
||||||
|
});
|
||||||
|
return newArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断路由 meta.roles 中是否包含当前登录用户权限字段
|
||||||
|
export function hasAuth(roles, route) {
|
||||||
|
if (route.meta && route.meta.roles) return roles.some((role) => route.meta.roles.includes(role));
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归过滤有权限的路由
|
||||||
|
export function setFilterMenuFun(routes, role) {
|
||||||
|
const menu = [];
|
||||||
|
routes.forEach((route) => {
|
||||||
|
const item = { ...route };
|
||||||
|
if (hasAuth(role, item)) {
|
||||||
|
if (item.children) item.children = setFilterMenuFun(item.children, role);
|
||||||
|
menu.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存多级嵌套数组处理后的一维数组(tagsView、菜单搜索中使用:未过滤隐藏的(isHide))
|
||||||
|
export function setCacheTagsViewRoutes(arr) {
|
||||||
|
// 先处理有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示
|
||||||
|
let rolesRoutes = setFilterMenuFun(arr, store.state.userInfos.userInfos.roles);
|
||||||
|
// 添加到 vuex setTagsViewRoutes 中
|
||||||
|
store.dispatch('tagsViewRoutes/setTagsViewRoutes', formatTwoStageRoutes(formatFlatteningRoutes(rolesRoutes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归处理多余的 layout : <router-view>,让需要访问的组件保持在第一层 layout 层。
|
||||||
|
// 因为 `keep-alive` 只能缓存二级路由
|
||||||
|
// 默认初始化时就执行
|
||||||
|
export function keepAliveSplice(to) {
|
||||||
|
if (to.matched && to.matched.length > 2) {
|
||||||
|
to.matched.map((v, k) => {
|
||||||
|
if (v.components.default instanceof Function) {
|
||||||
|
v.components.default().then((components) => {
|
||||||
|
if (components.default.name === 'parent') {
|
||||||
|
to.matched.splice(k, 1);
|
||||||
|
router.push({ path: to.path, query: to.query });
|
||||||
|
keepAliveSplice(to);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (v.components.default.name === 'parent') {
|
||||||
|
to.matched.splice(k, 1);
|
||||||
|
keepAliveSplice(to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理后端返回的 `component` 路径,拼装实现懒加载
|
||||||
|
export function loadView(path) {
|
||||||
|
/**
|
||||||
|
* 打包成一个 js、一个 css
|
||||||
|
*/
|
||||||
|
// if (path.indexOf('layout') > -1) return () => Promise.resolve(require(`@/${path}`));
|
||||||
|
// else return () => Promise.resolve(require(`@/views/${path}`));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打包成多个 js、多个 css
|
||||||
|
*/
|
||||||
|
if (path.indexOf('layout') > -1) return () => import(`@/${path}`);
|
||||||
|
else return () => import(`@/views/${path}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归处理每一项 `component` 中的路径
|
||||||
|
export function dynamicRouter(routes) {
|
||||||
|
return routes.map((view) => {
|
||||||
|
if (view.component) view.component = loadView(view.component);
|
||||||
|
if (view.children) dynamicRouter(view.children);
|
||||||
|
return view;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加路由,模拟数据与方法,可自行进行修改 admin
|
||||||
|
// 添加动态路由,`{ path: '*', redirect: '/404' }` 防止页面刷新,静态路由丢失问题
|
||||||
|
// next({ ...to, replace: true }) 动态路由 addRoute 完毕后才放行,防止刷新时 NProgress 进度条加载2次
|
||||||
|
// 文档地址:https://router.vuejs.org/zh/api/#router-addroutes
|
||||||
|
export function adminUser(router, to, next) {
|
||||||
|
resetRouter();
|
||||||
|
// 发请求获取路由表操作
|
||||||
|
// menuApi
|
||||||
|
// .getMenuAdmin()
|
||||||
|
// .then(async (res) => {
|
||||||
|
// // 获取路由表
|
||||||
|
// console.log(res.data);
|
||||||
|
// // 读取用户信息,获取对应权限进行判断
|
||||||
|
// store.dispatch('userInfos/setUserInfos');
|
||||||
|
// store.dispatch('routesList/setRoutesList', setFilterMenuFun(res.data, store.state.userInfos.userInfos.roles));
|
||||||
|
// dynamicRoutes[0].children = res.data;
|
||||||
|
// const awaitRoute = await dynamicRouter(dynamicRoutes);
|
||||||
|
// [...awaitRoute, { path: '*', redirect: '/404' }].forEach((route) => {
|
||||||
|
// router.addRoute({ ...route });
|
||||||
|
// });
|
||||||
|
// setCacheTagsViewRoutes(JSON.parse(JSON.stringify(res.data)));
|
||||||
|
// next({ ...to, replace: true });
|
||||||
|
// })
|
||||||
|
// .catch(() => {});
|
||||||
|
|
||||||
|
// 本地数据路由表操作
|
||||||
|
console.log(adminbendirout);
|
||||||
|
store.dispatch('userInfos/setUserInfos');
|
||||||
|
store.dispatch('routesList/setRoutesList', setFilterMenuFun(adminbendirout.data, store.state.userInfos.userInfos.roles));
|
||||||
|
dynamicRoutes[0].children = adminbendirout.data;
|
||||||
|
const awaitRoute = dynamicRouter(dynamicRoutes);
|
||||||
|
[...awaitRoute, { path: '*', redirect: '/404' }].forEach((route) => {
|
||||||
|
router.addRoute({ ...route });
|
||||||
|
});
|
||||||
|
setCacheTagsViewRoutes(JSON.parse(JSON.stringify(adminbendirout.data)));
|
||||||
|
next({ ...to, replace: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加路由,模拟数据与方法,可自行进行修改 test
|
||||||
|
// 添加动态路由,`{ path: '*', redirect: '/404' }` 防止页面刷新,静态路由丢失问题
|
||||||
|
export function testUser(router, to, next) {
|
||||||
|
resetRouter();
|
||||||
|
menuApi
|
||||||
|
.getMenuTest()
|
||||||
|
.then(async (res) => {
|
||||||
|
// 读取用户信息,获取对应权限进行判断
|
||||||
|
store.dispatch('userInfos/setUserInfos');
|
||||||
|
store.dispatch('routesList/setRoutesList', setFilterMenuFun(res.data, store.state.userInfos.userInfos.roles));
|
||||||
|
dynamicRoutes[0].children = res.data;
|
||||||
|
const awaitRoute = await dynamicRouter(dynamicRoutes);
|
||||||
|
[...awaitRoute, { path: '*', redirect: '/404' }].forEach((route) => {
|
||||||
|
router.addRoute({ ...route });
|
||||||
|
});
|
||||||
|
setCacheTagsViewRoutes(JSON.parse(JSON.stringify(res.data)));
|
||||||
|
next({ ...to, replace: true });
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置路由
|
||||||
|
export function resetRouter() {
|
||||||
|
router.matcher = createRouter().matcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟关闭进度条
|
||||||
|
export function delayNProgressDone(time = 300) {
|
||||||
|
setTimeout(() => {
|
||||||
|
NProgress.done();
|
||||||
|
}, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态加载后端返回路由路由(模拟数据)
|
||||||
|
export function getRouterList(router, to, next) {
|
||||||
|
if (!Session.get('userInfo')) return false;
|
||||||
|
if (Session.get('userInfo').userName === 'admin') adminUser(router, to, next);
|
||||||
|
else if (Session.get('userInfo').userName === 'test') testUser(router, to, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由加载前
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
keepAliveSplice(to);
|
||||||
|
NProgress.configure({ showSpinner: false });
|
||||||
|
if (to.meta.title && to.path !== '/login') NProgress.start();
|
||||||
|
let token = Session.get('token');
|
||||||
|
if (to.path === '/login' && !token) {
|
||||||
|
NProgress.start();
|
||||||
|
next();
|
||||||
|
delayNProgressDone();
|
||||||
|
} else {
|
||||||
|
if (!token) {
|
||||||
|
NProgress.start();
|
||||||
|
next('/login');
|
||||||
|
Session.clear();
|
||||||
|
delayNProgressDone();
|
||||||
|
} else if (token && to.path === '/login') {
|
||||||
|
next('/home');
|
||||||
|
delayNProgressDone();
|
||||||
|
} else {
|
||||||
|
if (Object.keys(store.state.routesList.routesList).length <= 0) {
|
||||||
|
getRouterList(router, to, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
delayNProgressDone(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 路由加载后
|
||||||
|
router.afterEach(() => {
|
||||||
|
PrevLoading.done();
|
||||||
|
delayNProgressDone();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 导出路由
|
||||||
|
export default router;
|
||||||
+12
-4
@@ -246,9 +246,11 @@ export function delayNProgressDone(time = 300) {
|
|||||||
|
|
||||||
// 动态加载后端返回路由路由(模拟数据)
|
// 动态加载后端返回路由路由(模拟数据)
|
||||||
export function getRouterList(router, to, next) {
|
export function getRouterList(router, to, next) {
|
||||||
if (!Session.get('userInfo')) return false;
|
if (!localStorage.getItem('token')) return false;
|
||||||
if (Session.get('userInfo').userName === 'admin') adminUser(router, to, next);
|
if (localStorage.getItem('token') ) {
|
||||||
else if (Session.get('userInfo').userName === 'test') testUser(router, to, next);
|
console.log('777777777777')
|
||||||
|
adminUser(router, to, next)
|
||||||
|
}else if (localStorage.getItem('userInfo').userName === 'test') testUser(router, to, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 路由加载前
|
// 路由加载前
|
||||||
@@ -256,24 +258,30 @@ router.beforeEach((to, from, next) => {
|
|||||||
keepAliveSplice(to);
|
keepAliveSplice(to);
|
||||||
NProgress.configure({ showSpinner: false });
|
NProgress.configure({ showSpinner: false });
|
||||||
if (to.meta.title && to.path !== '/login') NProgress.start();
|
if (to.meta.title && to.path !== '/login') NProgress.start();
|
||||||
let token = Session.get('token');
|
let token = localStorage.getItem('token');
|
||||||
if (to.path === '/login' && !token) {
|
if (to.path === '/login' && !token) {
|
||||||
|
console.log(111111111)
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
next();
|
next();
|
||||||
delayNProgressDone();
|
delayNProgressDone();
|
||||||
} else {
|
} else {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
console.log(2222222222)
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
next('/login');
|
next('/login');
|
||||||
Session.clear();
|
Session.clear();
|
||||||
delayNProgressDone();
|
delayNProgressDone();
|
||||||
} else if (token && to.path === '/login') {
|
} else if (token && to.path === '/login') {
|
||||||
|
console.log(33333333333)
|
||||||
next('/home');
|
next('/home');
|
||||||
delayNProgressDone();
|
delayNProgressDone();
|
||||||
} else {
|
} else {
|
||||||
|
console.log(4444444444)
|
||||||
if (Object.keys(store.state.routesList.routesList).length <= 0) {
|
if (Object.keys(store.state.routesList.routesList).length <= 0) {
|
||||||
|
console.log(55555)
|
||||||
getRouterList(router, to, next);
|
getRouterList(router, to, next);
|
||||||
} else {
|
} else {
|
||||||
|
console.log(6666666666)
|
||||||
next();
|
next();
|
||||||
delayNProgressDone(0);
|
delayNProgressDone(0);
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-1
@@ -1,6 +1,10 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
import { Session } from '@/utils/storage';
|
import { Session } from '@/utils/storage';
|
||||||
|
import { login } from '../views/login/api.js'
|
||||||
|
// import { login } from '@/login/api.js'
|
||||||
|
import jsonwebtoken from 'jsonwebtoken'
|
||||||
|
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
@@ -19,7 +23,45 @@ const state = {
|
|||||||
Authorization: `${Session.get('token')}`
|
Authorization: `${Session.get('token')}`
|
||||||
},
|
},
|
||||||
campusCalendarTempentUrl: process.env.VUE_APP_BASE_API, //
|
campusCalendarTempentUrl: process.env.VUE_APP_BASE_API, //
|
||||||
|
token: localStorage.getItem('token') || '',
|
||||||
|
refreshToken: localStorage.getItem('refreshToken') || '', // 刷新token
|
||||||
|
user: localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {}, // 用户信息
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Vuex.Store({ state, modules });
|
const mutations = {
|
||||||
|
changeToken( state, newToken ) {
|
||||||
|
state.token = newToken
|
||||||
|
localStorage.setItem('token', newToken)
|
||||||
|
},
|
||||||
|
changeRefreshToken( state, newRefreshToken ) {
|
||||||
|
state.refreshToken = newRefreshToken
|
||||||
|
localStorage.setItem('refreshToken', newRefreshToken)
|
||||||
|
},
|
||||||
|
changeUser( state, newUser ) {
|
||||||
|
state.user = newUser
|
||||||
|
localStorage.setItem('user', JSON.stringify(newUser) )
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
const actions = {
|
||||||
|
loginIn(store, obj) {
|
||||||
|
return new Promise((resolve, reject) =>{
|
||||||
|
login(obj).then(res =>{
|
||||||
|
console.log('=========================')
|
||||||
|
console.log(res)
|
||||||
|
store.commit('changeToken',res.token_type + ' ' + res.access_token )
|
||||||
|
store.commit('changeRefreshToken', res.refresh_token )
|
||||||
|
console.log(jsonwebtoken.decode(res.access_token))
|
||||||
|
store.commit('changeUser', jsonwebtoken.decode(res.access_token) )
|
||||||
|
resolve(res)
|
||||||
|
}).catch(err =>{
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Vuex.Store({ state, modules, mutations, actions });
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
const loginConfig = {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
loginConfig: { // 登录配置信息
|
||||||
|
client_id: 'test-client',
|
||||||
|
client_secret: '123456',
|
||||||
|
grant_type: 'dswj_multiple',
|
||||||
|
login_type: 'sms_login',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default loginConfig;
|
||||||
@@ -3,6 +3,7 @@ import router, { resetRouter } from '@/router/index';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Message, MessageBox } from 'element-ui';
|
import { Message, MessageBox } from 'element-ui';
|
||||||
import { Session } from '@/utils/storage';
|
import { Session } from '@/utils/storage';
|
||||||
|
const getToken = localStorage.getItem('token');
|
||||||
const errorCode = {
|
const errorCode = {
|
||||||
'401': '登录状态已过期,即将返回首页重新登录。',
|
'401': '登录状态已过期,即将返回首页重新登录。',
|
||||||
'403': '当前操作没有权限',
|
'403': '当前操作没有权限',
|
||||||
@@ -19,9 +20,10 @@ const service = axios.create({
|
|||||||
// 添加请求拦截器
|
// 添加请求拦截器
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config) => {
|
(config) => {
|
||||||
// 在发送请求之前做些什么 token
|
// 是否需要设置 token
|
||||||
if (Session.get('token')) {
|
const isToken = (config.headers || {}).isToken === false
|
||||||
config.headers.common['Authorization'] = `${Session.get('token')}`;
|
if (getToken && !isToken) {
|
||||||
|
config.headers['Authorization'] = localStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
@@ -34,6 +36,7 @@ service.interceptors.request.use(
|
|||||||
// 添加响应拦截器
|
// 添加响应拦截器
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(res) => {
|
(res) => {
|
||||||
|
console.log(res)
|
||||||
// 对响应数据做点什么
|
// 对响应数据做点什么
|
||||||
const response = res.data;
|
const response = res.data;
|
||||||
const code = res.data.code || 200;
|
const code = res.data.code || 200;
|
||||||
@@ -65,13 +68,14 @@ service.interceptors.response.use(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
console.log(error.response.error) // 获取错误状态码
|
||||||
// 对响应错误做点什么
|
// 对响应错误做点什么
|
||||||
if (error.message.indexOf('timeout') != -1) {
|
if (error.message.indexOf('timeout') != -1) {
|
||||||
Message.error('网络超时');
|
Message.error('网络超时');
|
||||||
} else if (error.message == 'Network Error') {
|
} else if (error.message == 'Network Error') {
|
||||||
Message.error('网络连接错误');
|
Message.error('网络连接错误');
|
||||||
} else {
|
} else {
|
||||||
Message.error(error.response.data.message);
|
Message.error(error.response.data.msg || error.response.data.error);
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
export function login (data) {
|
||||||
|
return request({
|
||||||
|
url: '/oauth2/token',
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
isToken: false,
|
||||||
|
},
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
export function getSmsCaptcha (phone) {
|
||||||
|
return request({
|
||||||
|
url: '/getSmsCaptcha',
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
isToken: false,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
phone
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
+129
-29
@@ -23,46 +23,49 @@
|
|||||||
<div class="login-main">
|
<div class="login-main">
|
||||||
<!-- <h4 class="login-title">{{ getThemeConfig.globalTitle }}</h4> -->
|
<!-- <h4 class="login-title">{{ getThemeConfig.globalTitle }}</h4> -->
|
||||||
<h4 class="login-title">数字校园教育管理平台</h4>
|
<h4 class="login-title">数字校园教育管理平台</h4>
|
||||||
<h5>请使用钉钉小程序扫码登录</h5>
|
<!-- <h5>请使用钉钉小程序扫码登录</h5> -->
|
||||||
<el-form class="el-form login-form">
|
<el-form class="el-form login-form">
|
||||||
<el-form-item style="margin-left: 0px" prop="userName">
|
<el-form-item style="margin-left: 0px" prop="phone">
|
||||||
<el-input
|
<el-input
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="$t('message.login.placeholder1')"
|
:placeholder="$t('message.login.placeholder1')"
|
||||||
prefix-icon="el-icon-user"
|
prefix-icon="el-icon-user"
|
||||||
v-model="ruleForm.userName"
|
v-model="loginForm.phone"
|
||||||
clearable
|
clearable
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
>
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="margin-left: 0px" prop="password">
|
<!-- <el-form-item style="margin-left: 0px" prop="code">
|
||||||
<el-input
|
<el-input
|
||||||
type="password"
|
type="code"
|
||||||
:placeholder="$t('message.login.placeholder2')"
|
:placeholder="$t('message.login.placeholder2')"
|
||||||
prefix-icon="el-icon-lock"
|
prefix-icon="el-icon-lock"
|
||||||
v-model="ruleForm.password"
|
v-model="loginForm.code"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:show-password="true"
|
:show-code="true"
|
||||||
>
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<el-form-item style="margin-left: 0px" prop="code">
|
<el-form-item style="margin-left: 0px" prop="code">
|
||||||
<div class="el-row" span="24">
|
<div class="el-row" span="24">
|
||||||
<div class="el-col el-col-16">
|
<div class="el-col el-col-14">
|
||||||
<el-input
|
<el-input
|
||||||
type="text"
|
type="text"
|
||||||
maxlength="4"
|
maxlength="4"
|
||||||
:placeholder="$t('message.login.placeholder3')"
|
:placeholder="$t('message.login.placeholder2')"
|
||||||
prefix-icon="el-icon-position"
|
prefix-icon="el-icon-lock"
|
||||||
v-model="ruleForm.code"
|
v-model="loginForm.code"
|
||||||
clearable
|
clearable
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
></el-input>
|
></el-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-col el-col-8">
|
<div class="el-col el-col-10">
|
||||||
<div class="login-code">
|
<div @click="onClickSendCode" class="login-code">
|
||||||
<span class="login-code-img">1234</span>
|
<!-- <span class="login-code-img" > -->
|
||||||
|
<!-- <i class="el-icon-position">{{ sendText }}</i> -->
|
||||||
|
<!-- </span> -->
|
||||||
|
<el-button class="el-icon-position" style="width: 100%;">{{ sendText }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -107,7 +110,8 @@ import { PrevLoading } from "@/utils/loading.js";
|
|||||||
import { quotationsList } from "./mock";
|
import { quotationsList } from "./mock";
|
||||||
import { useLoginApi } from "@/api/login";
|
import { useLoginApi } from "@/api/login";
|
||||||
import { Message } from "element-ui";
|
import { Message } from "element-ui";
|
||||||
|
import { rulesPhone } from '@/com/index.js'
|
||||||
|
import { getSmsCaptcha, login } from './api'
|
||||||
const LoginApi = useLoginApi();
|
const LoginApi = useLoginApi();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -120,15 +124,15 @@ export default {
|
|||||||
submit: {
|
submit: {
|
||||||
loading: false,
|
loading: false,
|
||||||
},
|
},
|
||||||
ruleForm: {
|
loginForm: {
|
||||||
userName: "admin",
|
phone: "18015724687",
|
||||||
password: "123456",
|
code: "",
|
||||||
code: "1234",
|
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
txt: "",
|
txt: "",
|
||||||
fun: null,
|
fun: null,
|
||||||
},
|
},
|
||||||
|
sendText: '发送'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -146,6 +150,10 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initRandomQuotations();
|
this.initRandomQuotations();
|
||||||
|
// console.log(localStorage.getItem('user'))
|
||||||
|
console.log('this.$store.state.loginConfig')
|
||||||
|
console.log(this.$store.state.loginConfig.loginConfig)
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 随机语录
|
// 随机语录
|
||||||
@@ -164,7 +172,101 @@ export default {
|
|||||||
// 登录按钮点击
|
// 登录按钮点击
|
||||||
submitForm() {
|
submitForm() {
|
||||||
this.submit.loading = true;
|
this.submit.loading = true;
|
||||||
// 登录发请求获取用户信息
|
this.$router.push('/evaluate')
|
||||||
|
console.log(this.$router)
|
||||||
|
localStorage.setItem('token', 123)
|
||||||
|
|
||||||
|
if( rulesPhone(this.loginForm.phone) ){ // 判断是否存在手机号验证码
|
||||||
|
if(this.loginForm.code){
|
||||||
|
// 登录发请求获取用户信息
|
||||||
|
let obj = {...this.$store.state.loginConfig.loginConfig, ...this.loginForm}
|
||||||
|
let formData = new FormData()
|
||||||
|
for( let key in obj){
|
||||||
|
formData.append(key, obj[key])
|
||||||
|
}
|
||||||
|
this.$store.dispatch('loginIn', formData).then(res =>{
|
||||||
|
this.$message.success('登录成功!')
|
||||||
|
// this.$router.push('/evaluate')
|
||||||
|
this.oldSet()
|
||||||
|
|
||||||
|
}).finally(err =>{
|
||||||
|
this.submit.loading = false;
|
||||||
|
this.sendText = '发送'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
this.$message.error('请输入正确的手机号!')
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
// 点击发送验证码
|
||||||
|
onClickSendCode() {
|
||||||
|
if( rulesPhone(this.loginForm.phone)){
|
||||||
|
if(this.sendText == '发送' || this.sendText == '重新发送'){
|
||||||
|
getSmsCaptcha(this.loginForm.phone).then(res =>{
|
||||||
|
this.sendText = '发送成功'
|
||||||
|
}).catch(err =>{
|
||||||
|
this.sendText = '重新发送'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
this.$message.error('请输入正确的手机号!')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 验证表单
|
||||||
|
rulesForm() {
|
||||||
|
// if(loginForm.phone){
|
||||||
|
|
||||||
|
// }
|
||||||
|
// this.loginForm.phone
|
||||||
|
},
|
||||||
|
oldSet() {
|
||||||
|
let defaultRoles = [];
|
||||||
|
let defaultAuthBtnList = [];
|
||||||
|
// admin 页面权限标识,对应路由 meta.roles
|
||||||
|
let adminRoles = ["admin"];
|
||||||
|
// admin 按钮权限标识
|
||||||
|
let adminAuthBtnList = ["btn.add", "btn.del", "btn.edit", "btn.link"];
|
||||||
|
// common 页面权限标识,对应路由 meta.roles
|
||||||
|
let testAuthPageList = ["common"];
|
||||||
|
// test 按钮权限标识
|
||||||
|
let testAuthBtnList = ["btn.add", "btn.link"];
|
||||||
|
if (this.loginForm.phone === "admin") {
|
||||||
|
defaultRoles = adminRoles;
|
||||||
|
defaultAuthBtnList = adminAuthBtnList;
|
||||||
|
} else {
|
||||||
|
defaultRoles = testAuthPageList;
|
||||||
|
defaultAuthBtnList = testAuthBtnList;
|
||||||
|
}
|
||||||
|
const userInfos = {
|
||||||
|
phone: this.loginForm.phone === "admin" ? "admin" : "test",
|
||||||
|
photo:
|
||||||
|
this.loginForm.phone === "admin"
|
||||||
|
? "https://img0.baidu.com/it/u=1833472230,3849481738&fm=253&fmt=auto?w=200&h=200"
|
||||||
|
: "https://img2.baidu.com/it/u=2187913762,2708298335&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
|
||||||
|
time: new Date().getTime(),
|
||||||
|
roles: defaultRoles,
|
||||||
|
authBtnList: defaultAuthBtnList,
|
||||||
|
};
|
||||||
|
// 存储用户信息到浏览器缓存
|
||||||
|
Session.set("userInfo", userInfos);
|
||||||
|
// 存储用户信息到vuex
|
||||||
|
this.$store.dispatch("userInfos/setUserInfos", userInfos);
|
||||||
|
PrevLoading.start();
|
||||||
|
this.$router.push("/");
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$message.success(
|
||||||
|
`${this.currentTime},${this.$t("message.login.signInText")}`
|
||||||
|
);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
clearInterval(this.time.fun);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let defaultRoles = [];
|
let defaultRoles = [];
|
||||||
let defaultAuthBtnList = [];
|
let defaultAuthBtnList = [];
|
||||||
@@ -176,7 +278,7 @@ export default {
|
|||||||
let testAuthPageList = ["common"];
|
let testAuthPageList = ["common"];
|
||||||
// test 按钮权限标识
|
// test 按钮权限标识
|
||||||
let testAuthBtnList = ["btn.add", "btn.link"];
|
let testAuthBtnList = ["btn.add", "btn.link"];
|
||||||
if (this.ruleForm.userName === "admin") {
|
if (this.loginForm.phone === "admin") {
|
||||||
defaultRoles = adminRoles;
|
defaultRoles = adminRoles;
|
||||||
defaultAuthBtnList = adminAuthBtnList;
|
defaultAuthBtnList = adminAuthBtnList;
|
||||||
} else {
|
} else {
|
||||||
@@ -184,9 +286,9 @@ export default {
|
|||||||
defaultAuthBtnList = testAuthBtnList;
|
defaultAuthBtnList = testAuthBtnList;
|
||||||
}
|
}
|
||||||
const userInfos = {
|
const userInfos = {
|
||||||
userName: this.ruleForm.userName === "admin" ? "admin" : "test",
|
phone: this.loginForm.phone === "admin" ? "admin" : "test",
|
||||||
photo:
|
photo:
|
||||||
this.ruleForm.userName === "admin"
|
this.loginForm.phone === "admin"
|
||||||
? "https://img0.baidu.com/it/u=1833472230,3849481738&fm=253&fmt=auto?w=200&h=200"
|
? "https://img0.baidu.com/it/u=1833472230,3849481738&fm=253&fmt=auto?w=200&h=200"
|
||||||
: "https://img2.baidu.com/it/u=2187913762,2708298335&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
|
: "https://img2.baidu.com/it/u=2187913762,2708298335&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
|
||||||
time: new Date().getTime(),
|
time: new Date().getTime(),
|
||||||
@@ -207,11 +309,8 @@ export default {
|
|||||||
);
|
);
|
||||||
}, 300);
|
}, 300);
|
||||||
}, 300);
|
}, 300);
|
||||||
},
|
*/
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
clearInterval(this.time.fun);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -344,6 +443,7 @@ export default {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all ease 0.2s;
|
transition: all ease 0.2s;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
font-weight: 400;
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--prev-border-color-hover);
|
border-color: var(--prev-border-color-hover);
|
||||||
transition: all ease 0.2s;
|
transition: all ease 0.2s;
|
||||||
|
|||||||
Reference in New Issue
Block a user