From 61e1c648b2a40169f790114dfc1312ced6f0cdb4 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Thu, 7 Aug 2025 11:01:46 +0800 Subject: [PATCH] perf: request key --- frontend/src/i18n/en.json | 9 +++++-- frontend/src/i18n/zh-CN.json | 9 +++++-- frontend/src/utils/request.ts | 49 ++++++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 23233b82..ef9bfc94 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -46,7 +46,8 @@ "not_exceed_50mb": "Supports XLS, XLSX, CSV formats, file size does not exceed 50MB", "reset_password": "Reset password", "password_reset_successful": "Password reset successful", - "or": "Or" + "or": "Or", + "refresh": "Refresh" }, "dashboard": { "open_dashboard": "Open Dashboard", @@ -562,5 +563,9 @@ "remark": "Remark", "back_community": "Restore to Community Edition", "confirm_tips": "Are you sure to restore to Community Edition?" + }, + "license": { + "error_tips": "Do you want to refresh the page?", + "offline_tips": "The service has been offline, please contact the administrator to restart the service!" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json index a7acba49..b644ff3d 100644 --- a/frontend/src/i18n/zh-CN.json +++ b/frontend/src/i18n/zh-CN.json @@ -46,7 +46,8 @@ "not_exceed_50mb": "支持 XLS、XLSX、CSV 格式,文件大小不超过 50MB", "reset_password": "重置密码", "password_reset_successful": "重置密码成功", - "or": "或者" + "or": "或者", + "refresh": "刷新" }, "dashboard": { "open_dashboard": "打开仪表板", @@ -562,5 +563,9 @@ "remark": "备注", "back_community": "还原至社区版", "confirm_tips": "确定还原至社区版?" + }, + "license": { + "error_tips": "是否刷新页面?", + "offline_tips": "服务已经下线,请联系管理员重启服务!" } -} \ No newline at end of file +} diff --git a/frontend/src/utils/request.ts b/frontend/src/utils/request.ts index e9ae6c17..5c0ad969 100644 --- a/frontend/src/utils/request.ts +++ b/frontend/src/utils/request.ts @@ -11,6 +11,8 @@ import axios, { import { useCache } from '@/utils/useCache' import { getLocale } from './utils' import { useAssistantStore } from '@/stores/assistant' +import { i18n } from '@/i18n' +const t = i18n.global.t const assistantStore = useAssistantStore() const { wsCache } = useCache() // Response data structure @@ -63,6 +65,11 @@ class HttpService { this.setupInterceptors() } + private cancelCurrentRequest(message: string) { + this.cancelTokenSource.cancel(message) + this.cancelTokenSource = axios.CancelToken.source() + } + private setupInterceptors() { // Request interceptor this.instance.interceptors.request.use( @@ -100,8 +107,15 @@ class HttpService { return config } - const request_key = LicenseGenerator.generate() - config.headers['X-SQLBOT-KEY'] = request_key + try { + const request_key = LicenseGenerator.generate() + config.headers['X-SQLBOT-KEY'] = request_key + } catch (e: any) { + if (e?.message?.includes('offline')) { + this.cancelCurrentRequest('license-key error detected') + showLicenseKeyError() + } + } // Request logging // console.log(`[Request] ${config.method?.toUpperCase()} ${config.url}`) @@ -211,6 +225,9 @@ class HttpService { // Show error using UI library (e.g., Element Plus, Ant Design) console.error(errorMessage) + /* if (errorMessage?.includes('Invalid license key salt')) { + showLicenseKeyError() + } */ // ElMessage.error(errorMessage) ElMessage({ message: errorMessage, @@ -265,8 +282,16 @@ class HttpService { heads['X-SQLBOT-ASSISTANT-ONLINE'] = assistantStore.getOnline } } - const request_key = LicenseGenerator.generate() - heads['X-SQLBOT-KEY'] = request_key + + try { + const request_key = LicenseGenerator.generate() + heads['X-SQLBOT-KEY'] = request_key + } catch (e: any) { + if (e?.message?.includes('offline')) { + controller?.abort('license-key error detected') + showLicenseKeyError() + } + } const real_url = import.meta.env.VITE_API_BASE_URL return fetch(real_url + url, { @@ -387,3 +412,19 @@ class HttpService { export const request = new HttpService({ baseURL: import.meta.env.VITE_API_BASE_URL, }) + +const showLicenseKeyError = (msg?: string) => { + ElMessageBox.confirm(t('license.error_tips'), { + confirmButtonType: 'primary', + tip: msg || t('license.offline_tips'), + confirmButtonText: t('common.refresh'), + cancelButtonText: t('common.cancel'), + customClass: 'confirm-no_icon', + autofocus: false, + callback: (value: string) => { + if (value === 'confirm') { + window.location.reload() + } + }, + }) +}