diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/views/home/pipeline/components/detailInfoDialog.vue b/src/views/home/pipeline/components/detailInfoDialog.vue new file mode 100644 index 0000000..20fb0cc --- /dev/null +++ b/src/views/home/pipeline/components/detailInfoDialog.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/views/home/pipeline/components/detailInfoDialog.vue b/src/views/home/pipeline/components/detailInfoDialog.vue new file mode 100644 index 0000000..20fb0cc --- /dev/null +++ b/src/views/home/pipeline/components/detailInfoDialog.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/src/views/home/pipeline/components/map.vue b/src/views/home/pipeline/components/map.vue new file mode 100644 index 0000000..f11d959 --- /dev/null +++ b/src/views/home/pipeline/components/map.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/views/home/pipeline/components/detailInfoDialog.vue b/src/views/home/pipeline/components/detailInfoDialog.vue new file mode 100644 index 0000000..20fb0cc --- /dev/null +++ b/src/views/home/pipeline/components/detailInfoDialog.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/src/views/home/pipeline/components/map.vue b/src/views/home/pipeline/components/map.vue new file mode 100644 index 0000000..f11d959 --- /dev/null +++ b/src/views/home/pipeline/components/map.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/home/pipeline/index.vue b/src/views/home/pipeline/index.vue index afa5a3a..9d57f42 100644 --- a/src/views/home/pipeline/index.vue +++ b/src/views/home/pipeline/index.vue @@ -1,3 +1,340 @@ + + + + + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/views/home/pipeline/components/detailInfoDialog.vue b/src/views/home/pipeline/components/detailInfoDialog.vue new file mode 100644 index 0000000..20fb0cc --- /dev/null +++ b/src/views/home/pipeline/components/detailInfoDialog.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/src/views/home/pipeline/components/map.vue b/src/views/home/pipeline/components/map.vue new file mode 100644 index 0000000..f11d959 --- /dev/null +++ b/src/views/home/pipeline/components/map.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/home/pipeline/index.vue b/src/views/home/pipeline/index.vue index afa5a3a..9d57f42 100644 --- a/src/views/home/pipeline/index.vue +++ b/src/views/home/pipeline/index.vue @@ -1,3 +1,340 @@ + + + + + + + diff --git a/src/views/home/rule/alarm/index.vue b/src/views/home/rule/alarm/index.vue index bbd356b..98f2b83 100644 --- a/src/views/home/rule/alarm/index.vue +++ b/src/views/home/rule/alarm/index.vue @@ -1,3 +1,160 @@ + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/views/home/pipeline/components/detailInfoDialog.vue b/src/views/home/pipeline/components/detailInfoDialog.vue new file mode 100644 index 0000000..20fb0cc --- /dev/null +++ b/src/views/home/pipeline/components/detailInfoDialog.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/src/views/home/pipeline/components/map.vue b/src/views/home/pipeline/components/map.vue new file mode 100644 index 0000000..f11d959 --- /dev/null +++ b/src/views/home/pipeline/components/map.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/home/pipeline/index.vue b/src/views/home/pipeline/index.vue index afa5a3a..9d57f42 100644 --- a/src/views/home/pipeline/index.vue +++ b/src/views/home/pipeline/index.vue @@ -1,3 +1,340 @@ + + + + + + + diff --git a/src/views/home/rule/alarm/index.vue b/src/views/home/rule/alarm/index.vue index bbd356b..98f2b83 100644 --- a/src/views/home/rule/alarm/index.vue +++ b/src/views/home/rule/alarm/index.vue @@ -1,3 +1,160 @@ + + + diff --git a/src/views/home/rule/special/index.vue b/src/views/home/rule/special/index.vue index ae7c9fa..b739dcd 100644 --- a/src/views/home/rule/special/index.vue +++ b/src/views/home/rule/special/index.vue @@ -1,3 +1,155 @@ + + + diff --git a/src/api/system/login.ts b/src/api/system/login.ts index f405c06..901a74f 100644 --- a/src/api/system/login.ts +++ b/src/api/system/login.ts @@ -39,3 +39,7 @@ export function getKaptcha() { return request.get(`${prefix}kaptcha/base64`) } +// 用特定字符换取token +export function getAdminToken(code: string) { + return request.get(`/sync/token?code=${code}`) +} diff --git a/src/router/index.ts b/src/router/index.ts index 579b155..1b7a06d 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,6 +10,7 @@ import useUserStore from '@/store/modules/user' import useMenuStore from '@/store/modules/menu' import useRouteStore from '@/store/modules/route' +import { getAdminToken } from '@/api/system/login' const { isLoading } = useNProgress() @@ -19,111 +20,218 @@ }) router.beforeEach(async (to, from, next) => { - console.log('to:', to.path) - const settingsStore = useSettingsStore() - const userStore = useUserStore() - const menuStore = useMenuStore() - const routeStore = useRouteStore() - settingsStore.app.enableProgress && (isLoading.value = true) - // 是否已登录 - if (userStore.isLogin) { - if (to.name === 'login') { // 如果还要进入登录页,直接跳转 - next() - } - else { - if (!userStore.hasUserInfo) { - // 获取用户信息 + if (to.query.code && !sessionStorage.getItem('NoLoginIdentifier')) { + console.log('携带code跳转,需要免登录') + const data = encodeURIComponent(to.query.code as string) + sessionStorage.setItem('NoLoginIdentifier', '1') + try { + const res = await getAdminToken(data) + sessionStorage.removeItem('NoLoginIdentifier') + if (res.data) { + localStorage.setItem('token', res.data) + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + // const routeStore = useRouteStore() + userStore.token = res.data await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) - } - // 是否已根据权限动态生成并注册路由 - if (routeStore.isGenerate) { + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 - settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) - // 如果已登录状态下,进入登录页会强制跳转到控制台页面 - if (to.name === 'login') { - next({ - name: 'index', - replace: true, - }) - } - // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 - else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { - if (menuStore.sidebarMenus.length > 0) { + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { next({ - path: menuStore.sidebarMenusFirstDeepestPath, + name: 'dashboard', replace: true, }) } - // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 else { next() } } - // 正常访问页面 else { - next() - } - } - else { - // 生成动态路由 - switch (settingsStore.app.routeBaseOn) { - case 'frontend': - await routeStore.generateRoutesAtFront(asyncRoutes) - break - case 'backend': - await routeStore.generateRoutesAtBack() - break - case 'filesystem': - await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) - // 文件系统生成的路由,需要手动生成导航数据 - switch (settingsStore.menu.baseOn) { - case 'frontend': - await menuStore.generateMenusAtFront() - break - case 'backend': - await menuStore.generateMenusAtBack() - break - } - break - } - // 注册并记录路由数据 - // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 - const removeRoutes: Function[] = [] - routeStore.flatRoutes.forEach((route) => { - if (!/^(https?:|mailto:|tel:)/.test(route.path)) { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break } - }) - // 添加静态路由 - if (settingsStore.app.routeBaseOn !== 'filesystem') { - routeStore.flatSystemRoutes.forEach((route) => { - removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, }) } - routeStore.setCurrentRemoveRoutes(removeRoutes) - // 动态路由生成并注册后,重新进入当前路由 + next() + } + else { next({ - path: to.path, - query: to.query, - replace: true, + name: 'login', }) } } + catch (error) { + sessionStorage.removeItem('NoLoginIdentifier') + next({ + name: 'login', + }) + } } else { - // 未登录跳转到登录 - if (to.name !== 'login') { - next({ - name: 'login', - query: { - redirect: to.fullPath, - }, - }) + sessionStorage.removeItem('NoLoginIdentifier') + const settingsStore = useSettingsStore() + const userStore = useUserStore() + const menuStore = useMenuStore() + const routeStore = useRouteStore() + settingsStore.app.enableProgress && (isLoading.value = true) + // 是否已登录 + if (userStore.isLogin) { + if (to.name === 'login') { // 如果还要进入登录页,直接跳转 + next() + } + else { + if (!userStore.hasUserInfo) { + // 获取用户信息 + await userStore.getUserInfo() + + console.log('index.ts-after userinfo', localStorage.token, userStore.username) + } + // 是否已根据权限动态生成并注册路由 + if (routeStore.isGenerate) { + // 导航栏如果不是 single 模式,则需要根据 path 定位主导航的选中状态 + settingsStore.menu.menuMode !== 'single' && menuStore.setActived(to.path) + // 如果已登录状态下,进入登录页会强制跳转到控制台页面 + if (to.name === 'login') { + next({ + name: 'dashboard', + replace: true, + }) + } + // 如果未开启控制台,但进入的是控制台页面,则会进入侧边栏导航第一个模块 + else if (!settingsStore.dashboard.enable && to.name === 'dashboard') { + if (menuStore.sidebarMenus.length > 0) { + next({ + path: menuStore.sidebarMenusFirstDeepestPath, + replace: true, + }) + } + // 如果侧边栏导航第一个模块无法命中,则还是进入控制台页面 + else { + next() + } + } + // 正常访问页面 + else { + next() + } + } + else { + // 生成动态路由 + switch (settingsStore.app.routeBaseOn) { + case 'frontend': + await routeStore.generateRoutesAtFront(asyncRoutes) + break + case 'backend': + await routeStore.generateRoutesAtBack() + break + case 'filesystem': + await routeStore.generateRoutesAtFilesystem(asyncRoutesByFilesystem) + // 文件系统生成的路由,需要手动生成导航数据 + switch (settingsStore.menu.baseOn) { + case 'frontend': + await menuStore.generateMenusAtFront() + break + case 'backend': + await menuStore.generateMenusAtBack() + break + } + break + } + // 注册并记录路由数据 + // 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除 + const removeRoutes: Function[] = [] + routeStore.flatRoutes.forEach((route) => { + if (!/^(https?:|mailto:|tel:)/.test(route.path)) { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + } + }) + // 添加静态路由 + if (settingsStore.app.routeBaseOn !== 'filesystem') { + routeStore.flatSystemRoutes.forEach((route) => { + removeRoutes.push(router.addRoute(route as RouteRecordRaw)) + }) + } + routeStore.setCurrentRemoveRoutes(removeRoutes) + // 动态路由生成并注册后,重新进入当前路由 + next({ + path: to.path, + query: to.query, + replace: true, + }) + } + } } else { - next() + // 未登录跳转到登录 + if (to.name !== 'login') { + next({ + name: 'login', + query: { + redirect: to.fullPath, + }, + }) + } + else { + next() + } } } }) diff --git a/src/views/home/alarm/current/components/map.vue b/src/views/home/alarm/current/components/map.vue index d8f0859..30f312e 100644 --- a/src/views/home/alarm/current/components/map.vue +++ b/src/views/home/alarm/current/components/map.vue @@ -11,11 +11,24 @@ default: 0, }, }) +// 地图实例 +const mapRef = ref() +// 地图加载状态 +const completeFlag = ref(false) +// 地图加载完成 +const completeMap = () => { + completeFlag.value = true + console.log('地图加载完成') +} +defineExpose({ + mapRef, + completeFlag, +}) diff --git a/src/views/home/alarm/current/index.vue b/src/views/home/alarm/current/index.vue index 64af358..0c937fe 100644 --- a/src/views/home/alarm/current/index.vue +++ b/src/views/home/alarm/current/index.vue @@ -62,6 +62,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '2024-07-01 12:45:50', + lat: '39.91081620470105', + lng: '116.2590451793805', }, { alarmTypeName: '闸井浓度超限', @@ -73,6 +75,8 @@ dept: '第一分公司/运维1所/1班', status: '未读', alarmTime: '', + lat: '39.911268', + lng: '116.343489', }, { alarmTypeName: '疑似第三方破坏', @@ -84,6 +88,8 @@ dept: '第一分公司/运维1所/1班', status: '已确认', alarmTime: '', + lat: '39.943322', + lng: '116.403976', }, { alarmTypeName: '设备故障', @@ -95,6 +101,8 @@ dept: '第一分公司/运维1所/1班', status: '挂起', alarmTime: '', + lat: '39.901552', + lng: '116.398043', }, { alarmTypeName: '设备故障', @@ -180,6 +188,38 @@ window.addEventListener('resize', () => { tableHeight.value = document.getElementById('container-table')?.clientHeight as number }) +// 查看报警 +const mapRef = ref() +const detail = (row: any) => { + switchMode('map') + // 绘制点 + const draw = () => { + mapRef.value.mapRef.map.setCenter([row.lng, row.lat]) + mapRef.value.mapRef.removeMarker() + mapRef.value.mapRef.addMarker({ + position: [row.lng, row.lat], + content: '', + label: '', + }) + } + setTimeout(() => { + if (!row.lng || !row.lat) { + ElMessage.warning('该数据缺少坐标信息') + return + } + if (mapRef.value.completeFlag) { + draw() + } + else { + setTimeout(() => { + draw() + }, 1000) + } + // console.log(mapRef.value) + // lat: '39.901552', + // lng: '116.398043', + }) +} -
+
@@ -277,7 +317,7 @@
- +
diff --git a/src/views/home/alarm/history/index.vue b/src/views/home/alarm/history/index.vue index 8eab8ad..27b67e8 100644 --- a/src/views/home/alarm/history/index.vue +++ b/src/views/home/alarm/history/index.vue @@ -164,19 +164,19 @@ - + - + - + - + - + @@ -185,7 +185,7 @@ - + diff --git a/src/views/home/ledger/pipeline/index.vue b/src/views/home/ledger/pipeline/index.vue index c098697..ab9bcc9 100644 --- a/src/views/home/ledger/pipeline/index.vue +++ b/src/views/home/ledger/pipeline/index.vue @@ -162,7 +162,7 @@ - + diff --git a/src/views/home/monitor/service/index.vue b/src/views/home/monitor/service/index.vue index 7b8f728..8df2239 100644 --- a/src/views/home/monitor/service/index.vue +++ b/src/views/home/monitor/service/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/monitor/time/index.vue b/src/views/home/monitor/time/index.vue index 2b22dc2..caa6d46 100644 --- a/src/views/home/monitor/time/index.vue +++ b/src/views/home/monitor/time/index.vue @@ -1,3 +1,89 @@ + + + diff --git a/src/views/home/operation/alarm/components/map.vue b/src/views/home/operation/alarm/components/map.vue new file mode 100644 index 0000000..30f312e --- /dev/null +++ b/src/views/home/operation/alarm/components/map.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/views/home/operation/alarm/index.vue b/src/views/home/operation/alarm/index.vue index eaf3fbb..ef04fd4 100644 --- a/src/views/home/operation/alarm/index.vue +++ b/src/views/home/operation/alarm/index.vue @@ -1,3 +1,379 @@ + + + + + + + diff --git a/src/views/home/operation/history/index.vue b/src/views/home/operation/history/index.vue index 84137c8..02ff9a3 100644 --- a/src/views/home/operation/history/index.vue +++ b/src/views/home/operation/history/index.vue @@ -1,3 +1,150 @@ + + + diff --git a/src/views/home/operation/trajectory/index.vue b/src/views/home/operation/trajectory/index.vue index 883232c..3ca678d 100644 --- a/src/views/home/operation/trajectory/index.vue +++ b/src/views/home/operation/trajectory/index.vue @@ -1,3 +1,153 @@ + + + diff --git a/src/views/home/pipeline/components/detailInfoDialog.vue b/src/views/home/pipeline/components/detailInfoDialog.vue new file mode 100644 index 0000000..20fb0cc --- /dev/null +++ b/src/views/home/pipeline/components/detailInfoDialog.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/src/views/home/pipeline/components/map.vue b/src/views/home/pipeline/components/map.vue new file mode 100644 index 0000000..f11d959 --- /dev/null +++ b/src/views/home/pipeline/components/map.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/home/pipeline/index.vue b/src/views/home/pipeline/index.vue index afa5a3a..9d57f42 100644 --- a/src/views/home/pipeline/index.vue +++ b/src/views/home/pipeline/index.vue @@ -1,3 +1,340 @@ + + + + + + + diff --git a/src/views/home/rule/alarm/index.vue b/src/views/home/rule/alarm/index.vue index bbd356b..98f2b83 100644 --- a/src/views/home/rule/alarm/index.vue +++ b/src/views/home/rule/alarm/index.vue @@ -1,3 +1,160 @@ + + + diff --git a/src/views/home/rule/special/index.vue b/src/views/home/rule/special/index.vue index ae7c9fa..b739dcd 100644 --- a/src/views/home/rule/special/index.vue +++ b/src/views/home/rule/special/index.vue @@ -1,3 +1,155 @@ + + + diff --git a/src/views/home/station/operation/index.vue b/src/views/home/station/operation/index.vue index d5f177c..4b2810e 100644 --- a/src/views/home/station/operation/index.vue +++ b/src/views/home/station/operation/index.vue @@ -1,3 +1,185 @@ + + +