This repository has been archived on 2025-10-29. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FPGA_WebLab/src/utils/BoardManager.ts

280 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ref } from "vue";
import { createInjectionState } from "@vueuse/core";
import { RemoteUpdateClient, DataClient, Board } from "@/APIClient";
import { isUndefined } from "lodash";
import { AuthManager } from "@/utils/AuthManager";
import { toFileParameterOrNull } from "./Common";
// 统一的板卡数据接口扩展原有的Board类型
export interface BoardData extends Board {
defaultBitstream: string;
goldBitstreamFile?: File;
appBitstream1File?: File;
appBitstream2File?: File;
appBitstream3File?: File;
}
const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
// 远程升级相关参数
const devPort = 1234;
const remoteUpdater = AuthManager.createClient(RemoteUpdateClient);
// 统一的板卡数据
const boards = ref<BoardData[]>([]);
// 获取位流编号
function getSelectedBitstreamNum(bitstreamName: string): number {
if (bitstreamName === "黄金位流") return 0;
if (bitstreamName === "应用位流1") return 1;
if (bitstreamName === "应用位流2") return 2;
if (bitstreamName === "应用位流3") return 3;
return 0;
}
// 获取所有板卡信息(管理员权限)
async function getAllBoards(): Promise<{ success: boolean; error?: string }> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.isAdminAuthenticated();
if (!hasAdminAuth) {
console.error("权限验证失败");
return { success: false, error: "权限不足" };
}
const client = AuthManager.createClient(DataClient);
const result = await client.getAllBoards();
if (result) {
// 将Board类型转换为BoardData类型添加默认值
boards.value = result.map((board) => {
return {
...board,
defaultBitstream: "黄金位流", // 设置默认位流
goldBitstreamFile: undefined,
appBitstream1File: undefined,
appBitstream2File: undefined,
appBitstream3File: undefined,
// Ensure methods from Board are present
init: board.init?.bind(board),
toJSON: board.toJSON?.bind(board),
};
});
console.log("获取板卡信息成功", result.length);
return { success: true };
} else {
console.error("获取板卡信息失败:返回结果为空");
return { success: false, error: "获取板卡信息失败" };
}
} catch (e: any) {
console.error("获取板卡信息异常:", e);
return { success: false, error: e.message || "获取板卡信息异常" };
}
}
// 新增板卡(管理员权限)
async function addBoard(
name: string,
): Promise<{ success: boolean; error?: string; boardId?: string }> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.isAdminAuthenticated();
if (!hasAdminAuth) {
console.error("权限验证失败");
return { success: false, error: "权限不足" };
}
// 验证输入参数
if (!name) {
console.error("参数验证失败", { name });
return { success: false, error: "参数不完整" };
}
const client = AuthManager.createClient(DataClient);
const boardId = await client.addBoard(name);
if (boardId) {
console.log("新增板卡成功", { boardId, name });
// 刷新板卡列表
await getAllBoards();
return { success: true };
} else {
console.error("新增板卡失败返回ID为空");
return { success: false, error: "新增板卡失败" };
}
} catch (e: any) {
console.error("新增板卡异常:", e);
if (e.status === 401) {
return { success: false, error: "权限不足" };
} else if (e.status === 400) {
return { success: false, error: "输入参数错误" };
} else {
return { success: false, error: e.message || "新增板卡异常" };
}
}
}
// 删除板卡(管理员权限)
async function deleteBoard(
boardId: string,
): Promise<{ success: boolean; error?: string }> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.isAdminAuthenticated();
if (!hasAdminAuth) {
console.error("权限验证失败");
return { success: false, error: "权限不足" };
}
if (!boardId) {
console.error("板卡ID为空");
return { success: false, error: "板卡ID不能为空" };
}
const client = AuthManager.createClient(DataClient);
const result = await client.deleteBoard(boardId);
if (result > 0) {
console.log("删除板卡成功", { boardId, deletedCount: result });
// 刷新板卡列表
await getAllBoards();
return { success: true };
} else {
console.error("删除板卡失败影响行数为0");
return { success: false, error: "删除板卡失败" };
}
} catch (e: any) {
console.error("删除板卡异常:", e);
if (e.status === 401) {
return { success: false, error: "权限不足" };
} else if (e.status === 400) {
return { success: false, error: "输入参数错误" };
} else {
return { success: false, error: e.message || "删除板卡异常" };
}
}
}
// 上传并固化位流
async function uploadAndDownloadBitstreams(
board: BoardData,
goldBitstream?: File,
appBitstream1?: File,
appBitstream2?: File,
appBitstream3?: File,
): Promise<{ success: boolean; error?: string }> {
let cnt = 0;
if (!isUndefined(goldBitstream)) cnt++;
if (!isUndefined(appBitstream1)) cnt++;
if (!isUndefined(appBitstream2)) cnt++;
if (!isUndefined(appBitstream3)) cnt++;
if (cnt === 0) {
console.error("未选择比特流文件");
return { success: false, error: "未选择比特流文件" };
}
try {
console.log("开始上传比特流", { boardIp: board.ipAddr, fileCount: cnt });
const uploadResult = await remoteUpdater.uploadBitstreams(
board.ipAddr,
toFileParameterOrNull(goldBitstream),
toFileParameterOrNull(appBitstream1),
toFileParameterOrNull(appBitstream2),
toFileParameterOrNull(appBitstream3),
);
if (!uploadResult) {
console.error("上传比特流失败");
return { success: false, error: "上传比特流失败" };
}
console.log("比特流上传成功,开始固化");
const downloadResult = await remoteUpdater.downloadMultiBitstreams(
board.ipAddr,
board.port,
getSelectedBitstreamNum(board.defaultBitstream),
);
if (downloadResult != cnt) {
console.error("固化比特流失败", {
expected: cnt,
actual: downloadResult,
});
return { success: false, error: "固化比特流失败" };
} else {
console.log("固化比特流成功", { count: downloadResult });
return { success: true };
}
} catch (e: any) {
console.error("比特流操作异常:", e);
return { success: false, error: e.message || "比特流操作异常" };
}
}
// 热启动位流
async function hotresetBitstream(
board: BoardData,
bitstreamNum: number,
): Promise<{ success: boolean; error?: string }> {
try {
console.log("开始热启动比特流", { boardIp: board.ipAddr, bitstreamNum });
const ret = await remoteUpdater.hotResetBitstream(
board.ipAddr,
board.port,
bitstreamNum,
);
if (ret) {
console.log("热启动比特流成功");
return { success: true };
} else {
console.error("热启动比特流失败");
return { success: false, error: "热启动比特流失败" };
}
} catch (e: any) {
console.error("热启动比特流异常:", e);
return { success: false, error: e.message || "热启动比特流异常" };
}
}
// 处理文件上传
function handleFileChange(
event: Event,
board: BoardData,
fileKey: keyof Pick<
BoardData,
| "goldBitstreamFile"
| "appBitstream1File"
| "appBitstream2File"
| "appBitstream3File"
>,
) {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
if (file) {
(board as any)[fileKey] = file;
console.log(`文件选择成功`, {
boardIp: board.ipAddr,
fileKey,
fileName: file.name,
});
}
}
return {
boards,
uploadAndDownloadBitstreams,
hotresetBitstream,
handleFileChange,
getSelectedBitstreamNum,
getAllBoards,
addBoard,
deleteBoard,
};
});
export { useProvideBoardManager, useBoardManager };