feat: 后端添加获取空闲实验板,继续修改前端界面使其更加合理

This commit is contained in:
2025-07-12 14:59:28 +08:00
parent 44e357b887
commit 0fb0c4e395
11 changed files with 222 additions and 117 deletions

View File

@@ -91,7 +91,7 @@
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { useBoardManager } from './BoardManager';
import { useBoardManager } from '../../utils/BoardManager';
// Props 和 Emits
interface Props {

View File

@@ -1,272 +0,0 @@
import { ref } from "vue";
import { createInjectionState } from "@vueuse/core";
import { RemoteUpdateClient, DataClient, Board } from "@/APIClient";
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 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 getAllBoards(): Promise<{ success: boolean; error?: string }> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.verifyAdminAuth();
if (!hasAdminAuth) {
console.error("权限验证失败");
return { success: false, error: "权限不足" };
}
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),
};
});
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,
ipAddr: string,
port: number,
): Promise<{ success: boolean; error?: string; boardId?: string }> {
try {
// 验证管理员权限
const hasAdminAuth = await AuthManager.verifyAdminAuth();
if (!hasAdminAuth) {
console.error("权限验证失败");
return { success: false, error: "权限不足" };
}
// 验证输入参数
if (!name || !ipAddr || !port) {
console.error("参数验证失败", { name, ipAddr, port });
return { success: false, error: "参数不完整" };
}
const client = AuthManager.createAuthenticatedClient();
const boardId = await client.addBoard(name, ipAddr, port);
if (boardId) {
console.log("新增板卡成功", { boardId, name, ipAddr, port });
// 刷新板卡列表
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.verifyAdminAuth();
if (!hasAdminAuth) {
console.error("权限验证失败");
return { success: false, error: "权限不足" };
}
if (!boardId) {
console.error("板卡ID为空");
return { success: false, error: "板卡ID不能为空" };
}
const client = AuthManager.createAuthenticatedClient();
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,
Common.toFileParameterOrNull(goldBitstream),
Common.toFileParameterOrNull(appBitstream1),
Common.toFileParameterOrNull(appBitstream2),
Common.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 };

View File

@@ -202,7 +202,7 @@
import { FlexRender } from "@tanstack/vue-table";
import { onMounted, ref } from "vue";
import { RefreshCw, Edit, Plus, Trash2 } from "lucide-vue-next";
import { useProvideBoardManager } from "./BoardManager";
import { useProvideBoardManager } from "../../utils/BoardManager";
import { useProvideBoardTableManager } from "./BoardTableManager";
import AddBoardDialog from "./AddBoardDialog.vue";

View File

@@ -15,8 +15,8 @@ import {
} from "@tanstack/vue-table";
import { h, ref, computed, version } from "vue";
import { createInjectionState } from "@vueuse/core";
import type { BoardData } from "./BoardManager";
import { useBoardManager } from "./BoardManager";
import type { BoardData } from "../../utils/BoardManager";
import { useBoardManager } from "../../utils/BoardManager";
import { useDialogStore } from "@/stores/dialog";
const [useProvideBoardTableManager, useBoardTableManager] =