diff --git a/package.json b/package.json index 775f02c8..d6916776 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/" }, "dependencies": { - "@antv/g6": "^4.2.6", + "@antv/g6": "^4.2.7", "axios": "^0.21.1", "clipboard": "^2.0.8", "countup.js": "^2.0.7", @@ -26,7 +26,7 @@ "vue-router": "^4.0.2", "vue-web-screen-shot": "^1.1.9", "vuex": "^4.0.0-rc.2", - "wangeditor": "^4.6.15" + "wangeditor": "^4.6.16" }, "devDependencies": { "@types/axios": "^0.14.0", diff --git a/src/router/index.ts b/src/router/index.ts index 376cc04e..d904e02f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -806,62 +806,63 @@ const router = createRouter({ routes: staticRoutes, }); -// 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 -export function getBackEndControlRoutes(callback: any) { +// 前端控制路由:初始化方法,防止刷新时丢失 +export function initAllFun() { + NextLoading.start(); const token = getSession('token'); if (!token) return false; - store.dispatch('userInfos/setUserInfos'); - const auth = store.state.userInfos.userInfos.authPageList[0]; // 模拟 admin 与 test - if (auth === 'admin') { - getMenuAdmin() - .then((res: any) => { - callback(res); - }) - .catch(() => {}); - } else { - getMenuTest() - .then((res: any) => { - callback(res); - }) - .catch(() => {}); - } -} - -// 后端控制路由,模拟执行路由数据初始化 -export function setBackEndControlRoutesFun(res: any, callback?: any) { - initBackEndControlRoutesFun(res); - window.location.href = window.location.href; // 防止页面刷新时,出现空白或404 - callback(res); -} - -// 后端控制路由,动态添加菜单时(刷新菜单) -export function setBackEndControlRefreshRoutes() { - getBackEndControlRoutes((res: any) => { - initBackEndControlRoutesFun(res); - }); -} - -// 后端控制路由,模拟执行路由数据初始化 -const initBackEndControlRoutesFun = (res: any) => { - NextLoading.start(); - const oldRoutes = JSON.parse(JSON.stringify(res.data)); - store.dispatch('requestOldRoutes/setBackEndControlRoutes', oldRoutes); - dynamicRoutes[0].children = backEndRouter(res.data); - resetRoute(); // 删除/重置路由 + store.dispatch('userInfos/setUserInfos'); // 触发初始化用户信息 router.addRoute(pathMatch); // 添加404界面 + resetRoute(); // 删除/重置路由 setAddRoute(); // 添加动态路由 setFilterMenu(); // 过滤权限菜单 setCacheTagsViewRoutes(); // 添加 keepAlive 缓存 -}; +} + +// 后端控制路由:模拟执行路由数据初始化 +export async function initBackEndControlRoutesFun() { + NextLoading.start(); // 界面 loading 动画开始执行 + const token = getSession('token'); // 获取浏览器缓存 token 值 + if (!token) return false; // 无 token 停止执行下一步 + store.dispatch('userInfos/setUserInfos'); // 触发初始化用户信息 + const res = await getBackEndControlRoutes(); // 获取路由 + const oldRoutes = JSON.parse(JSON.stringify(res.data)); // 获取接口原始路由(未处理component) + store.dispatch('requestOldRoutes/setBackEndControlRoutes', oldRoutes); // 存原始路由到 vuex 中 + dynamicRoutes[0].children = await backEndRouter(res.data); // 处理路由(component) + router.addRoute(pathMatch); // 添加404界面 + await setAddRoute(); // 添加动态路由 + setFilterMenu(); // 过滤权限菜单 + setCacheTagsViewRoutes(); // 添加 keepAlive 缓存 + setRefreshPagesRestore(); // 防止界面刷新时,出现404、空白、报错等 +} + +// 防止界面刷新时,出现404、空白、报错等 +export function setRefreshPagesRestore() { + const { matched, query, path } = router.currentRoute.value; + if (matched.length <= 0) router.push({ path, query }); +} + +// 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 +export function getBackEndControlRoutes() { + // 模拟 admin 与 test + const auth = store.state.userInfos.userInfos.authPageList[0]; + // 管理员 admin + if (auth === 'admin') return getMenuAdmin(); + // 其它用户 test + else return getMenuTest(); +} + +// 后端控制路由,动态添加菜单时(菜单管理界面刷新菜单,路径:/src/views/system/menu/component/addMenu.vue) +export function setBackEndControlRefreshRoutes() { + getBackEndControlRoutes(); +} // 后端控制路由,后端路由 component 转换 export function backEndRouter(routes: any) { if (!routes) return; return routes.map((item: any) => { - const { component } = item; - const { children } = item; - if (component) item.component = dynamicImport(dynamicViewsModules, component as string); - children && backEndRouter(children); + if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string); + item.children && backEndRouter(item.children); return item; }); } @@ -885,7 +886,7 @@ export function dynamicImport(dynamicViewsModules: Record Promise< // 多级嵌套数组处理成一维数组 export function formatFlatteningRoutes(arr: any) { - if (arr.length < 0) return false; + 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)); @@ -898,7 +899,7 @@ export function formatFlatteningRoutes(arr: any) { // 只保留二级:也就是二级以上全部处理成只有二级,keep-alive 支持二级缓存 // isKeepAlive 处理 `name` 值,进行缓存。顶级关闭,全部不缓存 export function formatTwoStageRoutes(arr: any) { - if (arr.length < 0) return false; + if (arr.length <= 0) return false; const newArr: any = []; const cacheList: Array = []; arr.forEach((v: any) => { @@ -983,26 +984,15 @@ export function resetRoute() { }); } -// 初始化方法,防止刷新时丢失 -export function initAllFun() { - NextLoading.start(); - const token = getSession('token'); - if (!token) return false; - store.dispatch('userInfos/setUserInfos'); // 触发初始化用户信息 - setAddRoute(); // 添加动态路由 - router.addRoute(pathMatch); // 添加404界面 - setFilterMenu(); // 过滤权限菜单 - setCacheTagsViewRoutes(); // 添加 keepAlive 缓存 -} - // 初始化方法执行 -const requestRoutes = store.state.themeConfig.themeConfig.isRequestRoutes; -if (!requestRoutes) initAllFun(); -// 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 -if (requestRoutes) - getBackEndControlRoutes((res: any) => { - setBackEndControlRoutesFun(res); - }); +const { isRequestRoutes } = store.state.themeConfig.themeConfig; +if (!isRequestRoutes) { + // 未开启后端控制路由 + initAllFun(); +} else if (isRequestRoutes) { + // 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 + initBackEndControlRoutesFun(); +} // 路由加载前 router.beforeEach((to, from, next) => { @@ -1022,7 +1012,7 @@ router.beforeEach((to, from, next) => { next('/home'); NProgress.done(); } else { - next(); + if (store.state.routesList.routesList.length > 0) next(); } } }); diff --git a/src/views/login/component/account.vue b/src/views/login/component/account.vue index 5db09b37..e7c86462 100644 --- a/src/views/login/component/account.vue +++ b/src/views/login/component/account.vue @@ -55,7 +55,7 @@ import { toRefs, reactive, defineComponent, computed } from 'vue'; import { useRouter } from 'vue-router'; import { ElMessage } from 'element-plus'; import { useI18n } from 'vue-i18n'; -import { initAllFun, getBackEndControlRoutes, setBackEndControlRoutesFun } from '/@/router/index.ts'; +import { initAllFun, initBackEndControlRoutesFun } from '/@/router/index.ts'; import { useStore } from '/@/store/index.ts'; import { setSession } from '/@/utils/storage.ts'; import { formatAxis } from '/@/utils/formatTime.ts'; @@ -80,7 +80,7 @@ export default defineComponent({ return formatAxis(new Date()); }); // 登录 - const onSignIn = () => { + const onSignIn = async () => { state.loading.signIn = true; let defaultAuthPageList: Array = []; let defaultAuthBtnList: Array = []; @@ -99,6 +99,7 @@ export default defineComponent({ defaultAuthPageList = testAuthPageList; defaultAuthBtnList = testAuthBtnList; } + // 用户信息模拟数据 const userInfos = { userName: state.ruleForm.userName, photo: @@ -115,18 +116,16 @@ export default defineComponent({ setSession('userInfo', userInfos); // 1、请注意执行顺序(存储用户信息到vuex) store.dispatch('userInfos/setUserInfos', userInfos); - // 前端控制路由,2、请注意执行顺序 if (!store.state.themeConfig.themeConfig.isRequestRoutes) { - initAllFun(); + // 前端控制路由,2、请注意执行顺序 + await initAllFun(); + signInSuccess(); + } else { + // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 + // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/" + await initBackEndControlRoutesFun(); + // 执行完 initBackEndControlRoutesFun,再执行 signInSuccess signInSuccess(); - } - // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 - else { - getBackEndControlRoutes((res: any) => { - setBackEndControlRoutesFun(res, () => { - signInSuccess(); - }); - }); } }; // 登录成功后的跳转 @@ -134,13 +133,14 @@ export default defineComponent({ // 初始化登录成功时间问候语 let currentTimeInfo = currentTime.value; // 登录成功,跳到转首页 + // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/" router.push('/'); // 登录成功提示 setTimeout(() => { + // 关闭 loading state.loading.signIn = true; const signInText = t('message.signInText'); ElMessage.success(`${currentTimeInfo},${signInText}`); - // 关闭 loading }, 300); }; return {