feat: 完善用户界面,添加绑定与解除绑定的功能

This commit is contained in:
2025-07-12 17:46:23 +08:00
parent 0fb0c4e395
commit f253a33c83
11 changed files with 1654 additions and 185 deletions

View File

@@ -1,4 +1,28 @@
import { DataClient } from "@/APIClient";
import {
DataClient,
VideoStreamClient,
BsdlParserClient,
DDSClient,
JtagClient,
MatrixKeyClient,
PowerClient,
RemoteUpdateClient,
TutorialClient,
UDPClient,
} from "@/APIClient";
// 支持的客户端类型联合类型
type SupportedClient =
| DataClient
| VideoStreamClient
| BsdlParserClient
| DDSClient
| JtagClient
| MatrixKeyClient
| PowerClient
| RemoteUpdateClient
| TutorialClient
| UDPClient;
export class AuthManager {
// 存储token到localStorage
@@ -21,30 +45,110 @@ export class AuthManager {
return await AuthManager.verifyToken();
}
// 为HTTP请求添加Authorization header
public static addAuthHeader(client: any): void {
// 通用的为HTTP请求添加Authorization header的方法
public static addAuthHeader(client: SupportedClient): void {
const token = AuthManager.getToken();
if (token && client.http) {
const originalFetch = client.http.fetch;
client.http.fetch = (url: RequestInfo, init?: RequestInit) => {
if (token) {
// 创建一个自定义的 http 对象,包装原有的 fetch 方法
const customHttp = {
fetch: (url: RequestInfo, init?: RequestInit) => {
if (!init) init = {};
if (!init.headers) init.headers = {};
// 添加Authorization header
if (typeof init.headers === "object" && init.headers !== null) {
(init.headers as any)["Authorization"] = `Bearer ${token}`;
}
// 使用全局 fetch 或 window.fetch
return (window as any).fetch(url, init);
},
};
// 重新构造客户端,传入自定义的 http 对象
const ClientClass = client.constructor as new (
baseUrl?: string,
http?: any,
) => SupportedClient;
const newClient = new ClientClass(undefined, customHttp);
// 将新客户端的属性复制到原客户端(这是一个 workaround
// 更好的做法是返回新的客户端实例
Object.setPrototypeOf(client, Object.getPrototypeOf(newClient));
Object.assign(client, newClient);
}
}
// 私有方法创建带认证的HTTP客户端
private static createAuthenticatedHttp() {
const token = AuthManager.getToken();
if (!token) {
return null;
}
return {
fetch: (url: RequestInfo, init?: RequestInit) => {
if (!init) init = {};
if (!init.headers) init.headers = {};
// 添加Authorization header
if (typeof init.headers === "object" && init.headers !== null) {
(init.headers as any)["Authorization"] = `Bearer ${token}`;
}
return originalFetch(url, init);
};
}
return (window as any).fetch(url, init);
},
};
}
// 创建已配置认证的API客户端
public static createAuthenticatedClient(): DataClient {
const client = new DataClient();
AuthManager.addAuthHeader(client);
return client;
// 通用的创建已认证客户端的方法(使用泛型)
public static createAuthenticatedClient<T extends SupportedClient>(
ClientClass: new (baseUrl?: string, http?: any) => T,
): T {
const customHttp = AuthManager.createAuthenticatedHttp();
return customHttp
? new ClientClass(undefined, customHttp)
: new ClientClass();
}
// 便捷方法:创建已配置认证的各种客户端
public static createAuthenticatedDataClient(): DataClient {
return AuthManager.createAuthenticatedClient(DataClient);
}
public static createAuthenticatedVideoStreamClient(): VideoStreamClient {
return AuthManager.createAuthenticatedClient(VideoStreamClient);
}
public static createAuthenticatedBsdlParserClient(): BsdlParserClient {
return AuthManager.createAuthenticatedClient(BsdlParserClient);
}
public static createAuthenticatedDDSClient(): DDSClient {
return AuthManager.createAuthenticatedClient(DDSClient);
}
public static createAuthenticatedJtagClient(): JtagClient {
return AuthManager.createAuthenticatedClient(JtagClient);
}
public static createAuthenticatedMatrixKeyClient(): MatrixKeyClient {
return AuthManager.createAuthenticatedClient(MatrixKeyClient);
}
public static createAuthenticatedPowerClient(): PowerClient {
return AuthManager.createAuthenticatedClient(PowerClient);
}
public static createAuthenticatedRemoteUpdateClient(): RemoteUpdateClient {
return AuthManager.createAuthenticatedClient(RemoteUpdateClient);
}
public static createAuthenticatedTutorialClient(): TutorialClient {
return AuthManager.createAuthenticatedClient(TutorialClient);
}
public static createAuthenticatedUDPClient(): UDPClient {
return AuthManager.createAuthenticatedClient(UDPClient);
}
// 登录函数
@@ -60,7 +164,7 @@ export class AuthManager {
AuthManager.setToken(token);
// 验证token
const authClient = AuthManager.createAuthenticatedClient();
const authClient = AuthManager.createAuthenticatedDataClient();
await authClient.testAuth();
return true;
@@ -85,7 +189,7 @@ export class AuthManager {
return false;
}
const client = AuthManager.createAuthenticatedClient();
const client = AuthManager.createAuthenticatedDataClient();
await client.testAuth();
return true;
} catch (error) {
@@ -102,7 +206,7 @@ export class AuthManager {
return false;
}
const client = AuthManager.createAuthenticatedClient();
const client = AuthManager.createAuthenticatedDataClient();
await client.testAdminAuth();
return true;
} catch (error) {
@@ -119,4 +223,10 @@ export class AuthManager {
return false;
}
}
// 检查客户端是否已配置认证
public static isClientAuthenticated(client: SupportedClient): boolean {
const token = AuthManager.getToken();
return !!token;
}
}

View File

@@ -41,7 +41,7 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
return { success: false, error: "权限不足" };
}
const client = AuthManager.createAuthenticatedClient();
const client = AuthManager.createAuthenticatedDataClient();
const result = await client.getAllBoards();
if (result) {
@@ -91,7 +91,7 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
return { success: false, error: "参数不完整" };
}
const client = AuthManager.createAuthenticatedClient();
const client = AuthManager.createAuthenticatedDataClient();
const boardId = await client.addBoard(name, ipAddr, port);
if (boardId) {
@@ -130,7 +130,7 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
return { success: false, error: "板卡ID不能为空" };
}
const client = AuthManager.createAuthenticatedClient();
const client = AuthManager.createAuthenticatedDataClient();
const result = await client.deleteBoard(boardId);
if (result > 0) {