Skip to content

Commit a988d59

Browse files
authored
perf: Optimize the timing for obtaining version information (#285)
1 parent 4b964e0 commit a988d59

File tree

11 files changed

+105
-56
lines changed

11 files changed

+105
-56
lines changed

i18n/locales/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
"InvalidCertificateGeneric": "Login failed: certificate or secure connection issue.",
133133
"NetworkError": "Login failed: network error. Please check connectivity.",
134134
"VersionIncompatible": "The client version is incompatible with JumpServer versions earlier than v4.10.12-lts. Please download and use the v3.0.7 client.",
135-
"VersionNoMatch": "The client version does not match the JumpServer version. Please download and use the v{version} client."
135+
"VersionNoMatch": "The client version does not match the JumpServer version. Please download and use the v{version} client, or upgrade JumpServer to the latest version."
136136
},
137137
"Asset": {
138138
"GetAssetFailed": "Get asset failed, please refresh and try again"

i18n/locales/zh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
"InvalidCertificateGeneric": "登录失败:证书或安全连接异常。",
131131
"NetworkError": "登录失败:网络异常,请检查连接",
132132
"VersionIncompatible": "客户端与JumpServer 版本(< v4.10.12-lts)不匹配,请下载使用 v3.0.7 的客户端",
133-
"VersionNoMatch": "客户端与 JumpServer 版本不匹配,请下载使用 v{version} 版本的客户端"
133+
"VersionNoMatch": "客户端与 JumpServer 版本不匹配,请下载使用 v{version} 版本的客户端或将 JumpServer 更新至最新"
134134
},
135135
"Loading": {
136136
"Loading": "加载中",

src-tauri/src/commands/auth_login.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,22 +237,13 @@ pub async fn auth_login(
237237

238238
// 发起请求
239239
let user_service = UserService::new(site.clone(), access_token.clone());
240-
let (profile, permission_orgs, current_org, xpack_message, version_message) = tokio::join!(
240+
let (profile, permission_orgs, current_org, xpack_message) = tokio::join!(
241241
user_service.get_user_profile(),
242242
user_service.get_permission_orgs(),
243243
user_service.get_current_org(),
244244
user_service.get_xpack_message(),
245-
user_service.get_version_message(),
246245
);
247246

248-
let version = if version_message.status == 200 && version_message.success {
249-
version_message.data
250-
} else if version_message.status == 404 {
251-
"incompatible".to_string()
252-
} else {
253-
"".to_string()
254-
};
255-
256247
let license_valid = if xpack_message.status == 200 && xpack_message.success {
257248
serde_json::from_str::<Value>(&xpack_message.data)
258249
.ok()
@@ -270,7 +261,6 @@ pub async fn auth_login(
270261
"login-success-detected",
271262
serde_json::json!({
272263
"status": "success",
273-
"version": version,
274264
"bearer": access_token,
275265
"profile": profile,
276266
"resolved_site": site,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use crate::service::version::VersionService;
2+
3+
#[tauri::command]
4+
pub async fn get_version_message(site: String) -> Result<String, String> {
5+
if site.trim().is_empty() {
6+
return Err("site is empty".to_string());
7+
}
8+
9+
let version_service = VersionService::new(site);
10+
let version_message = version_service.get_version_message().await;
11+
12+
if version_message.status == 200 && version_message.success {
13+
Ok(version_message.data)
14+
} else if version_message.status == 404 {
15+
Ok("incompatible".to_string())
16+
} else {
17+
Ok("".to_string())
18+
}
19+
}
20+

src-tauri/src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod get_assets;
44
pub mod get_config;
55
pub mod get_setting;
66
pub mod get_token;
7+
pub mod get_version_message;
78
pub mod list_system_fonts;
89
pub mod logout;
910
pub mod pull_up;

src-tauri/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::commands::get_assets::get_assets;
1313
use crate::commands::get_config::get_config;
1414
use crate::commands::get_setting::get_setting;
1515
use crate::commands::get_token::get_connect_token;
16+
use crate::commands::get_version_message::get_version_message;
1617
use crate::commands::http_callback::init_http_callback_server;
1718
use crate::commands::list_system_fonts::list_system_fonts;
1819
use crate::commands::logout::logout;
@@ -160,6 +161,7 @@ pub fn run() {
160161
minimize_window,
161162
get_asset_detail,
162163
get_connect_token,
164+
get_version_message,
163165
list_system_fonts,
164166
toggle_maximize_window,
165167
update_config_selection,

src-tauri/src/service/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ pub(crate) mod token;
88
pub(crate) mod token_oauth;
99
pub(crate) mod user;
1010
pub(crate) mod http_callback;
11+
pub(crate) mod version;

src-tauri/src/service/user.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,6 @@ impl UserService {
3232
get_with_response(&url, &self.bearer_token).await
3333
}
3434

35-
pub async fn get_version_message(&self) -> ApiResponse {
36-
let url = format!("{}/api/v1/settings/client/versions/", self.origin);
37-
log::info!("获取当前版本信息: {}", url);
38-
get_with_response(&url, &self.bearer_token).await
39-
}
40-
4135
pub async fn get_xpack_message(&self) -> ApiResponse {
4236
let url = format!("{}/api/v1/settings/public/", self.origin);
4337
log::info!("获取当前public信息: {}", url);

src-tauri/src/service/version.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use crate::commands::requests::{get_with_response, ApiResponse};
2+
3+
#[derive(Clone)]
4+
pub struct VersionService {
5+
origin: String,
6+
}
7+
8+
impl VersionService {
9+
pub fn new(origin: String) -> Self {
10+
Self { origin }
11+
}
12+
13+
pub async fn get_version_message(&self) -> ApiResponse {
14+
let url = format!("{}/api/v1/settings/client/versions/", self.origin);
15+
log::info!("获取当前版本信息: {}", url);
16+
// 该接口为公开接口,不需要 bearer_token
17+
get_with_response(&url, "").await
18+
}
19+
}
20+

ui/components/SideBar/profile.vue

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import type { LangType, ThemeType, UserData } from "~/types/index";
66
import { useSettingManager } from "~/composables/useSettingManager";
77
import { useUserInfoStore } from "~/store/modules/userInfo";
88
9+
interface VersionAlertPayload {
10+
type: string;
11+
version?: string;
12+
}
13+
914
const props = defineProps<{ collapse: boolean }>();
1015
1116
const toast = useToast();
@@ -203,6 +208,53 @@ function normalizeSite(value: string): string {
203208
return s.replace(/\/+$/, "");
204209
}
205210
211+
function normalizeVersionMessage(raw: string) {
212+
if (raw === "incompatible") {
213+
return { status: "incompatible" as const, versions: [] as string[] };
214+
}
215+
216+
if (!raw) {
217+
return { status: "list" as const, versions: [] as string[] };
218+
}
219+
220+
try {
221+
const parsed = JSON.parse(raw);
222+
const versions = Array.isArray(parsed)
223+
? parsed.map((item) => (item == null ? "" : String(item))).filter((v) => v.length > 0)
224+
: [];
225+
return { status: "list" as const, versions };
226+
} catch {
227+
return { status: "list" as const, versions: [] as string[] };
228+
}
229+
}
230+
231+
const emitVersionAlertAndCloseModal = (payload: VersionAlertPayload) => {
232+
openModal.value = false;
233+
loginBtn.value = false;
234+
useEventBus().emit("versionAlert", payload);
235+
};
236+
237+
const checkVersionBeforeOAuth = async (site: string) => {
238+
const [rawVersionMessage, appVersion] = await Promise.all([
239+
useTauriCoreInvoke<string>("get_version_message", { site }).catch(() => ""),
240+
useTauriAppGetVersion().catch(() => "")
241+
]);
242+
243+
const { status: versionStatus, versions } = normalizeVersionMessage(rawVersionMessage);
244+
245+
if (versionStatus === "incompatible") {
246+
emitVersionAlertAndCloseModal({ type: "incompatible" });
247+
return false;
248+
}
249+
250+
if (appVersion && versions.length > 0 && !versions.includes(appVersion)) {
251+
emitVersionAlertAndCloseModal({ type: "noMatch", version: versions[versions.length - 1] });
252+
return false;
253+
}
254+
255+
return true;
256+
};
257+
206258
/**
207259
* @description 打开登录页面
208260
*/
@@ -366,6 +418,9 @@ const handleConfirm = async () => {
366418
try {
367419
clearLoginBtnUnlockTimer();
368420
loginBtn.value = true;
421+
const ok = await checkVersionBeforeOAuth(normalizedSite);
422+
if (!ok) return;
423+
369424
await useTauriCoreInvoke("auth_login", {
370425
site: normalizedSite
371426
});

0 commit comments

Comments
 (0)