diff --git a/mayfly_go_web/package.json b/mayfly_go_web/package.json index a835acdf..d6a5df74 100644 --- a/mayfly_go_web/package.json +++ b/mayfly_go_web/package.json @@ -28,6 +28,7 @@ "screenfull": "^6.0.2", "sortablejs": "^1.15.0", "sql-formatter": "^12.1.2", + "uuid": "^9.0.1", "vue": "^3.3.4", "vue-clipboard3": "^1.0.1", "vue-router": "^4.2.5", diff --git a/mayfly_go_web/src/common/request.ts b/mayfly_go_web/src/common/request.ts index 0f20bbb9..f026f932 100755 --- a/mayfly_go_web/src/common/request.ts +++ b/mayfly_go_web/src/common/request.ts @@ -1,7 +1,7 @@ import router from '../router'; import Axios from 'axios'; import config from './config'; -import { getToken } from './utils/storage'; +import { getClientUuid, getToken, joinClientParams } from './utils/storage'; import { templateResolve } from './utils/string'; import { ElMessage } from 'element-plus'; @@ -54,6 +54,7 @@ service.interceptors.request.use( if (token) { // 设置token config.headers['Authorization'] = token; + config.headers['Client-Uuid'] = getClientUuid(); } return config; }, @@ -176,7 +177,7 @@ function del(url: string, params: any = null, headers: any = null, options: any function getApiUrl(url: string) { // 只是返回api地址而不做请求,用在上传组件之类的 - return baseUrl + url + '?token=' + getToken(); + return baseUrl + url + '?' + joinClientParams(); } export default { diff --git a/mayfly_go_web/src/common/sockets.ts b/mayfly_go_web/src/common/sockets.ts index aa1dc4a6..4ccda632 100644 --- a/mayfly_go_web/src/common/sockets.ts +++ b/mayfly_go_web/src/common/sockets.ts @@ -1,9 +1,9 @@ import Config from './config'; import { ElNotification, NotificationHandle } from 'element-plus'; import SocketBuilder from './SocketBuilder'; -import { getToken } from '@/common/utils/storage'; -import { createVNode, reactive } from "vue"; -import { buildProgressProps } from "@/components/progress-notify/progress-notify"; +import { getToken, joinClientParams } from '@/common/utils/storage'; +import { createVNode, reactive } from 'vue'; +import { buildProgressProps } from '@/components/progress-notify/progress-notify'; import ProgressNotify from '/src/components/progress-notify/progress-notify.vue'; export default { @@ -16,43 +16,40 @@ export default { return null; } const messageTypes = { - 0: "error", - 1: "success", - 2: "info", - } - const notifyMap: Map = new Map() + 0: 'error', + 1: 'success', + 2: 'info', + }; + const notifyMap: Map = new Map(); + const sysMsgUrl = `${Config.baseWsUrl}/sysmsg?${joinClientParams()}`; - return SocketBuilder.builder(`${Config.baseWsUrl}/sysmsg?token=${token}`) + return SocketBuilder.builder(sysMsgUrl) .message((event: { data: string }) => { const message = JSON.parse(event.data); - const type = messageTypes[message.type] + const type = messageTypes[message.type]; switch (message.category) { - case "execSqlFileProgress": - const content = JSON.parse(message.msg) - const id = content.id - let progress = notifyMap.get(id) + case 'execSqlFileProgress': + const content = JSON.parse(message.msg); + const id = content.id; + let progress = notifyMap.get(id); if (content.terminated) { if (progress != undefined) { - progress.notification?.close() - notifyMap.delete(id) - progress = undefined + progress.notification?.close(); + notifyMap.delete(id); + progress = undefined; } - return + return; } if (progress == undefined) { progress = { props: reactive(buildProgressProps()), notification: undefined, - } + }; } - progress.props.progress.title = content.title - progress.props.progress.executedStatements = content.executedStatements + progress.props.progress.title = content.title; + progress.props.progress.executedStatements = content.executedStatements; if (!notifyMap.has(id)) { - const vNodeMessage = createVNode( - ProgressNotify, - progress.props, - null, - ) + const vNodeMessage = createVNode(ProgressNotify, progress.props, null); progress.notification = ElNotification({ duration: 0, title: message.title, @@ -60,7 +57,7 @@ export default { type: type, showClose: false, }); - notifyMap.set(id, progress) + notifyMap.set(id, progress); } break; default: diff --git a/mayfly_go_web/src/common/utils/storage.ts b/mayfly_go_web/src/common/utils/storage.ts index 08c5646f..6e8739fc 100644 --- a/mayfly_go_web/src/common/utils/storage.ts +++ b/mayfly_go_web/src/common/utils/storage.ts @@ -1,6 +1,9 @@ +import { v1 as uuidv1 } from 'uuid'; + const TokenKey = 'token'; const UserKey = 'user'; const TagViewsKey = 'tagViews'; +const ClientUuid = 'clientUuid' // 获取请求token export function getToken(): string { @@ -48,6 +51,21 @@ export function removeTagViews() { removeSession(TagViewsKey); } +// 获取客户端UUID +export function getClientUuid(): string { + let uuid = getSession(ClientUuid) + if (uuid == null) { + uuid = uuidv1() + setSession(ClientUuid, uuid) + } + return uuid +} + +// 组装客户端参数,包括 token 和 clientUuid +export function joinClientParams(): string { + return `token=${getToken()}&clientUuid=${getClientUuid()}` +} + // 1. localStorage // 设置永久缓存 export function setLocal(key: string, val: any) { diff --git a/mayfly_go_web/src/views/login/component/AccountLogin.vue b/mayfly_go_web/src/views/login/component/AccountLogin.vue index 543f01d8..5bae8a1a 100644 --- a/mayfly_go_web/src/views/login/component/AccountLogin.vue +++ b/mayfly_go_web/src/views/login/component/AccountLogin.vue @@ -132,7 +132,7 @@ import { nextTick, onMounted, ref, toRefs, reactive, computed } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import { ElMessage } from 'element-plus'; import { initRouter } from '@/router/index'; -import { saveToken, saveUser } from '@/common/utils/storage'; +import { saveToken, saveUser, setSession } from '@/common/utils/storage'; import { formatAxis } from '@/common/utils/format'; import openApi from '@/common/openApi'; import { RsaEncrypt } from '@/common/rsa'; @@ -364,7 +364,7 @@ const loginResDeal = (loginRes: any) => { useUserInfo().setUserInfo(userInfos); const token = loginRes.token; - // 如果不需要otp校验,则该token即为accessToken,否则为otp校验token + // 如果不需要 otp校验,则该token即为accessToken,否则为otp校验token if (loginRes.otp == -1) { signInSuccess(token); return; @@ -385,6 +385,7 @@ const signInSuccess = async (accessToken: string = '') => { } // 存储 token 到浏览器缓存 saveToken(accessToken); + // 初始化路由 await initRouter(); diff --git a/mayfly_go_web/src/views/ops/db/DbList.vue b/mayfly_go_web/src/views/ops/db/DbList.vue index 1de92282..dfbc1389 100644 --- a/mayfly_go_web/src/views/ops/db/DbList.vue +++ b/mayfly_go_web/src/views/ops/db/DbList.vue @@ -172,7 +172,7 @@ import { ref, toRefs, reactive, onMounted, defineAsyncComponent } from 'vue'; import { ElMessage, ElMessageBox } from 'element-plus'; import { dbApi } from './api'; import config from '@/common/config'; -import { getToken } from '@/common/utils/storage'; +import { joinClientParams } from '@/common/utils/storage'; import { isTrue } from '@/common/assert'; import { Search as SearchIcon } from '@element-plus/icons-vue'; import { dateFormat } from '@/common/utils/date'; @@ -406,7 +406,7 @@ const dumpDbs = () => { 'href', `${config.baseApiUrl}/dbs/${state.exportDialog.dbId}/dump?db=${state.exportDialog.value.join(',')}&type=${type}&extName=${ state.exportDialog.extName - }&token=${getToken()}` + }&${joinClientParams()}` ); a.click(); state.exportDialog.visible = false; diff --git a/mayfly_go_web/src/views/ops/db/component/tab/Query.vue b/mayfly_go_web/src/views/ops/db/component/tab/Query.vue index 31f54bd2..998d71cb 100644 --- a/mayfly_go_web/src/views/ops/db/component/tab/Query.vue +++ b/mayfly_go_web/src/views/ops/db/component/tab/Query.vue @@ -88,7 +88,7 @@