289 lines
7.8 KiB
TypeScript
289 lines
7.8 KiB
TypeScript
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 };
|