FPGA_WebLab/src/views/User/BoardManager.ts

289 lines
7.8 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 { useDialogStore } from "@/stores/dialog";
import { useAlertStore } from "@/components/Alert";
import { Common } from "@/utils/Common";
import { isUndefined } from "lodash";
import { AuthManager } from "@/utils/AuthManager";
// 统一的板卡数据接口扩展原有的Board类型
export interface BoardData extends Board {
defaultBitstream: string;
goldBitstreamFile?: File;
appBitstream1File?: File;
appBitstream2File?: File;
appBitstream3File?: File;
}
const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
const dialog = useDialogStore();
const alert = useAlertStore();
// 远程升级相关参数
const devPort = 1234;
const remoteUpdater = new 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 fetchBoardsData(): Promise<boolean> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.verifyAdminAuth();
if (!hasAdminAuth) {
return false;
}
const client = AuthManager.createAuthenticatedClient();
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),
};
});
return true;
} else {
return false;
}
} catch (e) {
console.error(e);
return false;
}
}
// 获取所有板卡信息(管理员权限)- 显示提示信息,供外部调用
async function getAllBoards(): Promise<boolean> {
const result = await fetchBoardsData();
if (result) {
dialog.info("获取板卡信息成功");
} else {
dialog.warn("获取板卡信息失败");
}
return result;
}
// 新增板卡(管理员权限)
async function addBoard(
name: string,
ipAddr: string,
port: number,
): Promise<boolean> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.verifyAdminAuth();
if (!hasAdminAuth) {
dialog.error("需要管理员权限");
return false;
}
// 验证输入参数
if (!name || !ipAddr || !port) {
dialog.error("请填写完整的板卡信息");
return false;
}
const client = AuthManager.createAuthenticatedClient();
const boardId = await client.addBoard(name, ipAddr, port);
if (boardId) {
// 静默刷新板卡列表,不显示重复提示
await fetchBoardsData();
dialog.info("新增板卡成功");
return true;
} else {
dialog.warn("新增板卡失败");
return false;
}
} catch (e: any) {
if (e.status === 401) {
dialog.error("权限不足,需要管理员权限");
} else if (e.status === 400) {
dialog.error("输入参数错误");
} else {
dialog.error("新增板卡失败");
}
console.error(e);
return false;
}
}
// 删除板卡(管理员权限)
async function deleteBoard(boardId: string): Promise<boolean> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.verifyAdminAuth();
if (!hasAdminAuth) {
dialog.error("需要管理员权限");
return false;
}
if (!boardId) {
dialog.error("板卡ID不能为空");
return false;
}
const client = AuthManager.createAuthenticatedClient();
const result = await client.deleteBoard(boardId);
if (result > 0) {
// 静默刷新板卡列表,不显示重复提示
await fetchBoardsData();
dialog.info("删除板卡成功");
return true;
} else {
dialog.warn("删除板卡失败");
return false;
}
} catch (e: any) {
if (e.status === 401) {
dialog.error("权限不足,需要管理员权限");
} else if (e.status === 400) {
dialog.error("输入参数错误");
} else {
dialog.error("删除板卡失败");
}
console.error(e);
return false;
}
}
// 上传并固化位流
async function uploadAndDownloadBitstreams(
board: BoardData,
goldBitstream?: File,
appBitstream1?: File,
appBitstream2?: File,
appBitstream3?: File,
) {
let cnt = 0;
if (!isUndefined(goldBitstream)) cnt++;
if (!isUndefined(appBitstream1)) cnt++;
if (!isUndefined(appBitstream2)) cnt++;
if (!isUndefined(appBitstream3)) cnt++;
if (cnt === 0) {
dialog.error("未选择比特流");
return;
}
try {
const uploadResult = await remoteUpdater.uploadBitstreams(
board.ipAddr, // 使用板卡的IP地址
Common.toFileParameterOrNull(goldBitstream),
Common.toFileParameterOrNull(appBitstream1),
Common.toFileParameterOrNull(appBitstream2),
Common.toFileParameterOrNull(appBitstream3),
);
if (!uploadResult) {
dialog.warn("上传比特流出错");
return;
}
const downloadResult = await remoteUpdater.downloadMultiBitstreams(
board.ipAddr,
board.port,
getSelectedBitstreamNum(board.defaultBitstream),
);
if (downloadResult != cnt) {
dialog.warn("固化比特流出错");
} else {
dialog.info("固化比特流成功");
}
} catch (e) {
dialog.error("比特流上传错误");
console.error(e);
}
}
// 热启动位流
async function hotresetBitstream(board: BoardData, bitstreamNum: number) {
try {
const ret = await remoteUpdater.hotResetBitstream(
board.ipAddr,
board.port,
bitstreamNum,
);
if (ret) {
dialog.info("切换比特流成功");
} else {
dialog.error("切换比特流失败");
}
} catch (e) {
dialog.error("切换比特流失败");
console.error(e);
}
}
// 刷新板卡数据 - 简化逻辑,避免重复提示
async function refreshData() {
try {
const result = await fetchBoardsData();
if (result) {
alert?.info("刷新数据成功");
} else {
alert?.error("获取板卡信息失败");
}
} catch (e) {
alert?.error("获取数据失败");
console.error(e);
}
}
// 处理文件上传
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;
}
}
return {
boards,
uploadAndDownloadBitstreams,
hotresetBitstream,
refreshData,
handleFileChange,
getSelectedBitstreamNum,
getAllBoards,
fetchBoardsData,
addBoard,
deleteBoard,
};
});
export { useProvideBoardManager, useBoardManager };