登录失效跳转修复

This commit is contained in:
2026-08-12 10:47:18 +08:00
parent 10097f3003
commit d29075e9b4
11 changed files with 2151 additions and 759 deletions

20
components.d.ts vendored Normal file
View File

@@ -0,0 +1,20 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
Chart: typeof import('./src/components/chart/index.vue')['default']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModalProvider: typeof import('naive-ui')['NModalProvider']
ProviderHelper: typeof import('./src/components/ProviderHelper.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

2732
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -15,19 +15,22 @@
"echarts": "^5.4.3",
"echarts-liquidfill": "^3.1.0",
"jsencrypt": "^3.5.4",
"naive-ui": "^2.44.1",
"ol": "^7.4.0",
"pinia": "^3.0.4",
"prettier": "^3.0.0",
"vue": "^3.2.47",
"vue-router": "^4.6.4"
"vue": "^3.5.39",
"vue-router": "^5.1.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.1.0",
"@vitejs/plugin-vue-jsx": "^1.3.3",
"@vicons/fluent": "^0.12.0",
"@vitejs/plugin-vue": "^6.0.8",
"@vitejs/plugin-vue-jsx": "^5.1.6",
"@vue/compiler-sfc": "^3.5.39",
"less": "^4.1.3",
"typescript": "^4.9.3",
"vite": "^4.2.0",
"vue-tsc": "^1.2.0"
"naive-ui": "^2.44.1",
"typescript": "^7.0.2",
"unplugin-vue-components": "^28.7.0",
"vite": "8.1.4",
"vue-tsc": "^3.3.9"
}
}

View File

@@ -43,7 +43,18 @@ onBeforeUnmount(() => {
<template>
<div class="screen-adapter">
<div class="screen-adapter__inner" :style="adapterStyle">
<RouterView />
<n-loading-bar-provider>
<n-modal-provider>
<n-dialog-provider>
<n-message-provider>
<n-message-provider>
<provider-helper />
<router-view />
</n-message-provider>
</n-message-provider>
</n-dialog-provider>
</n-modal-provider>
</n-loading-bar-provider>
</div>
</div>
</template>

View File

@@ -0,0 +1,21 @@
<template>
<div></div>
</template>
<script>
import { useLoadingBar, useMessage, useModal } from 'naive-ui'
/**
* naive-ui的弹窗类的都没有提供全局方法, 这里挂载到window对象上
*/
export default {
name: 'ProviderHelper',
setup() {
window.$message = useMessage()
window.$loadingBar = useLoadingBar()
window.$modal = useModal()
}
}
</script>
<style scoped></style>

View File

@@ -4,16 +4,12 @@ import App from "./App.vue";
import Chart from "./components/chart/index.vue";
import * as echarts from "echarts";
import echartsConfig from "./config/echarts.config";
import { createDiscreteApi } from "naive-ui";
import { createPinia } from "pinia";
import router from "./router";
import './router/routerGuard'
echarts.registerTheme("t-theme", echartsConfig);
const { message, dialog } = createDiscreteApi(["message", "dialog"]);
window.$message = message;
window.$modal = dialog;
const app = createApp(App);
app.use(createPinia());

View File

@@ -75,21 +75,6 @@ const router = createRouter({
routes,
});
const whiteList = ["/login"];
router.beforeEach((to) => {
const hasToken = Boolean(getToken());
if (!hasToken && !whiteList.includes(to.path)) {
return {
path: "/login",
query: { redirect: to.fullPath },
};
}
return true;
});
export function resetRouter() {
// 当前项目暂无动态 addRoute 路由,保留该方法兼容登出流程。
}

60
src/router/routerGuard.js Normal file
View File

@@ -0,0 +1,60 @@
import router from './index'
import { getToken } from '@/utils/auth'
import { useUserStore } from '@/store/modules/user.js'
const whiteList = ['/login'] // no redirect whitelist
// const setPageTitle = function (meta) {
// let title = '海灵标'
// if (meta && meta.title) {
// title = `${meta.title}`
// }
// document.title = title
// }
// 路由守卫
router.beforeEach(async (to, from, next) => {
$loadingBar.start()
// setPageTitle(to.meta)
const hasToken = getToken()
const userStore = useUserStore()
if (hasToken) {
if (to.path === '/login') {
next({ path: '/' })
$loadingBar.finish()
} else {
const hasGetUserInfo = userStore.name
if (hasGetUserInfo !== '') {
next()
} else {
try {
// get user info
const infoVO = await userStore.getInfo()
next({ ...to, replace: true })
} catch (error) {
await userStore.resetToken()
next(`/login?redirect=${to.path}`)
// remove token and go to login page to re-login
console.error(error)
$loadingBar.error()
}
}
}
} else {
/* has no token */
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
next(`/login?redirect=${to.path}`)
$loadingBar.finish()
}
}
})
router.afterEach((to) => {
if (to.matched.length === 0) {
router.push('/404')
// fixme 不能自动跳转404, 需要引导
}
$loadingBar.finish()
})

View File

@@ -58,9 +58,8 @@ service.interceptors.response.use(
window.$message.error(error.response.data.msg, {
duration: 5 * 1000,
});
} else {
handleNoLogin();
}
handleNoLogin();
} else {
handleNoLogin();
}

View File

@@ -1624,19 +1624,19 @@ function getStatusClass(status: DeviceItem["status"]) {
</div>
<div class="video-panel">
<div class="video-screen">
<img src="/image.png" alt="" class="monitor-video">
<!-- <video v-if="currentMonitorVideo" ref="monitorVideoRef" :key="currentMonitorVideo"
<!-- <img src="/image.png" alt="" class="monitor-video"> -->
<video v-if="currentMonitorVideo" ref="monitorVideoRef" :key="currentMonitorVideo"
:class="['monitor-video', { infrared: activeCameraMode === 'infrared' }]" autoplay muted
playsinline></video> -->
playsinline></video>
<div class="scan-line"></div>
<!-- <div class="video-overlay top-left">实时视频流</div>
<div class="video-overlay top-left">实时视频流</div>
<div class="video-overlay top-right">
{{ activeCameraMode === "white" ? "白光镜头" : "红外镜头" }}
</div> -->
</div>
<div class="video-overlay bottom-left">{{ currentRobot.id }}</div>
<!-- <div v-if="streamLoading" class="video-empty">视频流连接中...</div>
<div v-if="streamLoading" class="video-empty">视频流连接中...</div>
<div v-else-if="streamError" class="video-empty">{{ streamError }}</div>
<div v-else-if="!currentMonitorVideo" class="video-empty">当前机器人暂无视频地址</div> -->
<div v-else-if="!currentMonitorVideo" class="video-empty">当前机器人暂无视频地址</div>
</div>
</div>
</div>

View File

@@ -1,6 +1,8 @@
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { resolve } from 'path'
import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
// import { viteSingleFile } from 'vite-plugin-singlefile'
@@ -11,6 +13,9 @@ export default ({ command }) => {
plugins: [
vue(),
vueJsx(),
Components({
resolvers: [NaiveUiResolver()]
}),
],
define: {
__VUE_OPTIONS_API__: false // 关闭 Vue2 中的 options选项API
@@ -25,7 +30,7 @@ export default ({ command }) => {
host: true,
proxy: {
'/api': {
target: `http://192.168.3.110:16003/`,
target: `http://127.0.0.1:16003/`,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},