Browse Source

fix: 添加iframe嵌套逻辑

sy-water-data-board-ui
panyuyi 1 month ago
parent
commit
073547c588
  1. 22
      src/components/Iframe/index.vue
  2. 85
      src/layout/Iframe.vue
  3. 13
      src/layout/components/Navbar.vue
  4. 18
      src/layout/index.vue
  5. 155
      src/router/index.js
  6. 112
      src/store/modules/permission.js

22
src/components/Iframe/index.vue

@ -0,0 +1,22 @@
<template>
<div class="iframe-page">
<iframe class="w-full h-full" :src="url"></iframe>
</div>
</template>
<script>
export default {
data() {
return {
url: "https://www.baidu.com",
};
},
created() {},
methods: {},
};
</script>
<style scoped lang="scss">
.iframe-page {
width: 100%;
height: 100%;
}
</style>

85
src/layout/Iframe.vue

@ -0,0 +1,85 @@
<template>
<div class="app-wrapper">
<div :class="{ 'fixed-header': true }">
<navbar />
</div>
<div class="wp">
<iframe
class="w-full h-full"
:src="url"
frameborder="no"
style="border: none"
></iframe>
</div>
</div>
</template>
<script>
import { Navbar } from "./components";
export default {
components: {
Navbar,
},
data() {
return {};
},
created() {
// console.log(this.$route);
},
computed: {
url: function () {
if (this.$route.query.url) return atob(this.$route.query.url);
},
},
methods: {},
};
</script>
<style scoped lang="scss">
@import "~@/assets/styles/mixin.scss";
@import "~@/assets/styles/variables.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
// background: #eef3ff;
background: #f4f9f7;
&.mobile.openSidebar {
position: fixed;
top: 0;
}
.wp {
padding-top: 56px;
}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
// width: calc(100% - #{$sideBarWidth});
width: 100%;
transition: width 0.28s;
}
.wp {
height: 100%;
.main-container {
height: 100%;
}
}
</style>

13
src/layout/components/Navbar.vue

@ -148,10 +148,7 @@ export default {
},
methods: {
handleSelectTab(e) {
if (e.label === "一张图") {
this.handleJump(e.value);
return;
}
console.log("handleSelectTab >>> ", e);
sessionStorage.setItem("topTab", e.value);
this.$store.dispatch("changeTopTab", e.value);
if (e.value === "sluice") {
@ -168,6 +165,14 @@ export default {
timestamp: new Date().getTime(),
},
});
} else if (e.label === "一张图") {
console.log("e >>> ", e);
this.$router.push({
path: "/iframe",
query: {
url: btoa(e.path),
},
});
} else {
this.$router.replace({
path: "/",

18
src/layout/index.vue

@ -1,22 +1,4 @@
<template>
<!-- <div :class="classObj" class="app-wrapper">-->
<!-- <div-->
<!-- v-if="device === 'mobile' && sidebar.opened"-->
<!-- class="drawer-bg"-->
<!-- @click="handleClickOutside"-->
<!-- />-->
<!-- <sidebar class="sidebar-container" />-->
<!-- <div :class="{ hasTagsView: needTagsView }" class="main-container">-->
<!-- <div :class="{ 'fixed-header': fixedHeader }">-->
<!-- <navbar />-->
<!-- <tags-view v-if="needTagsView" />-->
<!-- </div>-->
<!-- <app-main ref="appmain" />-->
<!-- <right-panel v-if="showSettings">-->
<!-- <settings />-->
<!-- </right-panel>-->
<!-- </div>-->
<!-- </div>-->
<div :class="classObj" class="app-wrapper">
<div :class="{ 'fixed-header': true }">
<navbar />

155
src/router/index.js

@ -1,11 +1,11 @@
import Vue from 'vue'
import Router from 'vue-router'
import { setToken,removeToken } from "@/utils/auth";
import Vue from "vue";
import Router from "vue-router";
import { setToken, removeToken } from "@/utils/auth";
Vue.use(Router)
Vue.use(Router);
/* Layout */
import Layout from '@/layout'
import Layout from "@/layout";
/**
* Note: 路由配置项
@ -28,58 +28,57 @@ import Layout from '@/layout'
// 公共路由
export const constantRoutes = [
{
path: '/redirect',
path: "/redirect",
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: (resolve) => require(['@/views/redirect'], resolve)
}
]
path: "/redirect/:path(.*)",
component: (resolve) => require(["@/views/redirect"], resolve),
},
],
},
{
path: '/login',
component: (resolve) => require(['@/views/login'], resolve),
hidden: true
path: "/login",
component: (resolve) => require(["@/views/login"], resolve),
hidden: true,
},
{
path: '/singleLogin',
component: (resolve) => require(['@/views/singleLogin'], resolve),
hidden: true
path: "/singleLogin",
component: (resolve) => require(["@/views/singleLogin"], resolve),
hidden: true,
},
{
path: '/tttt',
component: (resolve) => require(['@/views/system/testD3/index'], resolve),
hidden: true
path: "/tttt",
component: (resolve) => require(["@/views/system/testD3/index"], resolve),
hidden: true,
},
{
path: '/404',
component: (resolve) => require(['@/views/error/404'], resolve),
hidden: true
path: "/404",
component: (resolve) => require(["@/views/error/404"], resolve),
hidden: true,
},
{
path: '/401',
component: (resolve) => require(['@/views/error/401'], resolve),
hidden: true
path: "/401",
component: (resolve) => require(["@/views/error/401"], resolve),
hidden: true,
},
{
path: "/iframe",
component: (resolve) => require(["@/layout/Iframe.vue"], resolve),
},
{
path: '',
path: "",
component: Layout,
redirect: 'welcome',
redirect: "welcome",
children: [
{
path: 'welcome',
component: (resolve) => require(['@/views/welcome/index'], resolve),
path: "welcome",
component: (resolve) => require(["@/views/welcome/index"], resolve),
// name: '首页',
// meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
},
{
path: '/overviewStatistics',
component: (resolve) => require(['@/views/dike/runManage/enginerring/overviewStatistics/index.vue'], resolve),
hidden: true
},
]
],
},
//TODO 临时测试路径
@ -119,81 +118,81 @@ export const constantRoutes = [
// ]
// },
{
path: '/dict',
path: "/dict",
component: Layout,
hidden: true,
children: [
{
path: 'type/data/:id',
component: (resolve) => require(['@/views/system/dict/data'], resolve),
name: 'Data',
meta: { title: '字典数据', icon: '' }
}
]
path: "type/data/:id",
component: (resolve) => require(["@/views/system/dict/data"], resolve),
name: "Data",
meta: { title: "字典数据", icon: "" },
},
],
},
{
path: '/job',
path: "/job",
component: Layout,
hidden: true,
children: [
{
path: 'log',
component: (resolve) => require(['@/views/monitor/job/log'], resolve),
name: 'JobLog',
meta: { title: '调度日志' }
}
]
path: "log",
component: (resolve) => require(["@/views/monitor/job/log"], resolve),
name: "JobLog",
meta: { title: "调度日志" },
},
],
},
{
path: '/gen',
path: "/gen",
component: Layout,
hidden: true,
children: [
{
path: 'edit/:id',
component: (resolve) => require(['@/views/tool/gen/editTable'], resolve),
name: 'GenEdit',
meta: { title: '修改生成配置' }
}
]
}
]
const createRouter = () => new Router({
mode: 'hash', // 去掉url中的#
base:"/admin/",
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
path: "edit/:id",
component: (resolve) =>
require(["@/views/tool/gen/editTable"], resolve),
name: "GenEdit",
meta: { title: "修改生成配置" },
},
],
},
];
const createRouter = () =>
new Router({
mode: "hash", // 去掉url中的#
base: "/admin/",
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes,
});
const router = createRouter()
const router = createRouter();
// 注册一个全局前置守卫
router.beforeEach((to, from, next) => {
if (to.path === "/singleLogin") {
console.log("单点登录设置token", to.query.token); //判断当前路由是否需要进行权限控制
console.log("单点登录设置token", to.query.token); //判断当前路由是否需要进行权限控制
if (to.query.token) {
setToken(to.query.token);
if (to.query.page === 'null') {
next("/dike/engineeringCondition/dikeBaseInfo")
if (to.query.page === "null") {
next("/dike/engineeringCondition/dikeBaseInfo");
} else if (to.query.page) {
next(to.query.page)
next(to.query.page);
} else {
next("/dike/engineeringCondition/dikeBaseInfo")
next("/dike/engineeringCondition/dikeBaseInfo");
}
}
} else {
next() // 放行
next(); // 放行
}
})
});
// 重置路由
export const resetRouter = () => {
const newRouter = createRouter()
router.matcher = newRouter.matcher
const newRouter = createRouter();
router.matcher = newRouter.matcher;
// 重置白名单
// const resetWhiteNameList = ['/redirect', '/login']
// console.log('router >>>>> ', router)
@ -203,6 +202,6 @@ export const resetRouter = () => {
// router.hasRoute(path) && router.removeRoute(path)
// }
// })
}
};
export default router
export default router;

112
src/store/modules/permission.js

@ -1,6 +1,7 @@
import { constantRoutes, resetRouter } from '@/router';
import { getRouters } from '@/api/menu';
import Layout from '@/layout/index';
import { constantRoutes, resetRouter } from "@/router";
import { getRouters } from "@/api/menu";
import Layout from "@/layout/index";
import Iframe from "@/layout/Iframe";
/**
* selectTab = 'reservoir', //水库运行管理
@ -8,9 +9,9 @@ import Layout from '@/layout/index';
* selectTab = 'dike', // 堤防运行管理
*/
// 提取路由
const pickRoutes = ['/reservoir', '/dike', '/sluice', '/aiSupervision'];
const pickRoutes = ["/reservoir", "/dike", "/sluice", "/aiSupervision"];
// 根据meta.title提取的路由
const pickRouteNames = ['一张图']
const pickRouteNames = ["一张图"];
const permission = {
state: {
@ -18,8 +19,8 @@ const permission = {
routes: [],
addRoutes: [],
originRoutes: [],
selectTab: sessionStorage.getItem('topTab') || 'dike',
namesJumpMenu: [] // 跳转菜单
selectTab: sessionStorage.getItem("topTab") || "dike",
namesJumpMenu: [], // 跳转菜单
},
mutations: {
SET_ROUTES: (state, { routes, originRoutes }) => {
@ -32,12 +33,12 @@ const permission = {
},
SET_SELECT_TAB: (state, select) => {
state.selectTab = select;
}
},
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
console.log('生成路由 >>>>> ');
console.log("生成路由 >>>>> ");
return new Promise((resolve) => {
// 向后端请求路由数据
getRouters().then((res) => {
@ -142,10 +143,14 @@ const permission = {
// }
// )
const accessedRoutes = filterAsyncRouter(res.data);
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true });
const { newRoutes: dealAccessedRoutes, topTabList } = resolveChildrenRoutes(accessedRoutes);
commit('SET_ROUTES', { routes: dealAccessedRoutes, originRoutes: accessedRoutes });
commit('SET_TAB_LIST', topTabList);
accessedRoutes.push({ path: "*", redirect: "/404", hidden: true });
const { newRoutes: dealAccessedRoutes, topTabList } =
resolveChildrenRoutes(accessedRoutes);
commit("SET_ROUTES", {
routes: dealAccessedRoutes,
originRoutes: accessedRoutes,
});
commit("SET_TAB_LIST", topTabList);
resolve(dealAccessedRoutes);
});
});
@ -153,16 +158,16 @@ const permission = {
// 根据顶部tab切换路由
changeRoutes({ commit }) {
commit('SET_ROUTES', { routes: [] });
commit("SET_ROUTES", { routes: [] });
resetRouter();
},
// 切换tab
changeTopTab({ commit, dispatch }, payload) {
commit('SET_SELECT_TAB', payload);
dispatch('changeRoutes');
}
}
commit("SET_SELECT_TAB", payload);
dispatch("changeRoutes");
},
},
};
// 遍历后台传来的路由字符串,转换为组件对象
@ -170,8 +175,10 @@ function filterAsyncRouter(asyncRouterMap) {
return asyncRouterMap.filter((route) => {
if (route.component) {
// Layout组件特殊处理
if ( route.component === 'Layout') {
if (route.component === "Layout") {
route.component = Layout;
} else if (route.component === "Iframe" || route.component === "iframe") {
route.component = Iframe;
} else {
route.component = loadView(route.component);
}
@ -195,41 +202,48 @@ function resolveChildrenRoutes(routes, pickRoute = permission.state.selectTab) {
tempRoutesArr.push(v);
}
// 只要是名称叫“一张图”的都不展示在菜单上
if(v.meta?.title && pickRouteNames.includes(v.meta.title)) {
if(!v.hidden) tempRoutesNameArr.push({
...v,
label: v.meta.title,
value: v.path
})
if (v.meta?.title && pickRouteNames.includes(v.meta.title)) {
if (!v.hidden)
tempRoutesNameArr.push({
...v,
label: v.meta.title,
value: v.path,
});
}
return !pickRoutes.includes(v.path) && v.meta?.title !== '一张图';
return !pickRoutes.includes(v.path) && v.meta?.title !== "一张图";
});
if (tempRoutesArr.length) {
let parentRoute = tempRoutesArr.filter((v) => v.path === pickRoutePath)?.[0];
let parentRoute = tempRoutesArr.filter(
(v) => v.path === pickRoutePath
)?.[0];
if (parentRoute) {
newChildrenRoutes =
parentRoute.children?.map((v) => {
return {
...v,
path: `${parentRoute.path}/${v.path}`
};
})?.map(v=> {
if(v.path && v.path != '/' && (!v.children || !v.children.length)){
// 为了让非目录的一级菜单正常展示
parentRoute.children
?.map((v) => {
return {
path: '/',
orderNum: v.orderNum,
meta: v.meta,
component: Layout,
hidden: v.hidden,
children: [
v
]
...v,
path: `${parentRoute.path}/${v.path}`,
};
})
?.map((v) => {
if (
v.path &&
v.path != "/" &&
(!v.children || !v.children.length)
) {
// 为了让非目录的一级菜单正常展示
return {
path: "/",
orderNum: v.orderNum,
meta: v.meta,
component: Layout,
hidden: v.hidden,
children: [v],
};
} else {
return v;
}
} else {
return v
}
}) || [];
}) || [];
}
}
@ -241,10 +255,10 @@ function resolveChildrenRoutes(routes, pickRoute = permission.state.selectTab) {
return {
orderNum: v.orderNum,
label: v.meta.title,
value: v.path.slice(1)
value: v.path.slice(1),
};
}),
newRoutes: [...newChildrenRoutes, ...newRoutes]
newRoutes: [...newChildrenRoutes, ...newRoutes],
};
}

Loading…
Cancel
Save