feat: 前端完成适配后端api
This commit is contained in:
parent
8789d6f9ee
commit
da6386c6f0
|
@ -50,10 +50,31 @@ const [useAlertProvider, useAlertStore] = createInjectionState(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convenience methods for different alert types
|
||||||
|
function error(message: string, duration = 2000) {
|
||||||
|
show(message, "error", duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
function info(message: string, duration = 2000) {
|
||||||
|
show(message, "info", duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
function warn(message: string, duration = 2000) {
|
||||||
|
show(message, "warning", duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
function success(message: string, duration = 2000) {
|
||||||
|
show(message, "success", duration);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
alertState,
|
alertState,
|
||||||
show,
|
show,
|
||||||
hide,
|
hide,
|
||||||
|
error,
|
||||||
|
info,
|
||||||
|
warn,
|
||||||
|
success,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,7 @@
|
||||||
<h1 class="text-3xl font-bold mb-6">FPGA 设备管理</h1>
|
<h1 class="text-3xl font-bold mb-6">FPGA 设备管理</h1>
|
||||||
<button
|
<button
|
||||||
class="btn btn-ghost text-error hover:underline"
|
class="btn btn-ghost text-error hover:underline"
|
||||||
@click="
|
@click="toggleEditMode"
|
||||||
() => {
|
|
||||||
isEditMode = !isEditMode;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</button>
|
</button>
|
||||||
|
@ -17,7 +13,9 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="flex flex-row justify-between items-center mb-4">
|
<div class="flex flex-row justify-between items-center mb-4">
|
||||||
<h2 class="card-title">IP 地址列表</h2>
|
<h2 class="card-title">IP 地址列表</h2>
|
||||||
<button class="btn btn-ghost" @click="refreshData">刷新</button>
|
<button class="btn btn-ghost" @click="boardManager.refreshData">
|
||||||
|
刷新
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 搜索和列控制 -->
|
<!-- 搜索和列控制 -->
|
||||||
|
@ -185,45 +183,20 @@ import {
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useVueTable,
|
useVueTable,
|
||||||
} from "@tanstack/vue-table";
|
} from "@tanstack/vue-table";
|
||||||
import { isNull, isUndefined } from "lodash";
|
import { h, onMounted, ref } from "vue";
|
||||||
import { h, ref } from "vue";
|
import { useProvideBoardManager, type BoardData } from "./BoardManager";
|
||||||
import { RemoteUpdateClient } from "@/APIClient";
|
|
||||||
import { useDialogStore } from "@/stores/dialog";
|
|
||||||
import { Common } from "@/utils/Common";
|
|
||||||
|
|
||||||
const dialog = useDialogStore();
|
// 使用 BoardManager
|
||||||
|
const boardManager = useProvideBoardManager()!;
|
||||||
|
|
||||||
// 编辑状态
|
// 编辑状态
|
||||||
const isEditMode = ref(false);
|
const isEditMode = ref(false);
|
||||||
|
function toggleEditMode() {
|
||||||
// 远程升级相关参数
|
isEditMode.value = !isEditMode.value;
|
||||||
const devPort = 1234;
|
|
||||||
const remoteUpdater = new RemoteUpdateClient();
|
|
||||||
|
|
||||||
// 设备数据接口
|
|
||||||
export interface DeviceData {
|
|
||||||
id: string;
|
|
||||||
devAddr: string;
|
|
||||||
version: string;
|
|
||||||
defaultBitstream: string;
|
|
||||||
goldBitstreamFile?: File;
|
|
||||||
appBitstream1File?: File;
|
|
||||||
appBitstream2File?: File;
|
|
||||||
appBitstream3File?: File;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模拟数据,实际应该从API获取
|
|
||||||
const data = ref<DeviceData[]>([
|
|
||||||
{
|
|
||||||
id: "1",
|
|
||||||
devAddr: "192.168.1.100",
|
|
||||||
version: "v1.2.3",
|
|
||||||
defaultBitstream: "黄金位流",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns: ColumnDef<DeviceData>[] = [
|
const columns: ColumnDef<BoardData>[] = [
|
||||||
{
|
{
|
||||||
id: "select",
|
id: "select",
|
||||||
header: ({ table }) =>
|
header: ({ table }) =>
|
||||||
|
@ -258,18 +231,19 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
? h("input", {
|
? h("input", {
|
||||||
type: "text",
|
type: "text",
|
||||||
class: "input input-sm w-full",
|
class: "input input-sm w-full",
|
||||||
value: device.devAddr,
|
value: device.ipAddr,
|
||||||
onInput: (e: Event) => {
|
onInput: (e: Event) => {
|
||||||
device.devAddr = (e.target as HTMLInputElement).value;
|
device.ipAddr = (e.target as HTMLInputElement).value;
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: h("span", { class: "font-medium" }, device.devAddr);
|
: h("span", { class: "font-medium" }, device.ipAddr);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "version",
|
accessorKey: "version",
|
||||||
header: "版本号",
|
header: "版本号",
|
||||||
cell: ({ row }) => row.getValue("version"),
|
cell: ({ row }) =>
|
||||||
|
h("span", { class: "font-mono" }, row.original.firmVersion),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "defaultBitstream",
|
accessorKey: "defaultBitstream",
|
||||||
|
@ -303,7 +277,7 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
type: "file",
|
type: "file",
|
||||||
class: "file-input file-input-primary file-input-sm",
|
class: "file-input file-input-primary file-input-sm",
|
||||||
onChange: (e: Event) =>
|
onChange: (e: Event) =>
|
||||||
handleFileChange(e, device, "goldBitstreamFile"),
|
boardManager.handleFileChange(e, device, "goldBitstreamFile"),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -316,7 +290,7 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
type: "file",
|
type: "file",
|
||||||
class: "file-input file-input-secondary file-input-sm",
|
class: "file-input file-input-secondary file-input-sm",
|
||||||
onChange: (e: Event) =>
|
onChange: (e: Event) =>
|
||||||
handleFileChange(e, device, "appBitstream1File"),
|
boardManager.handleFileChange(e, device, "appBitstream1File"),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -329,7 +303,7 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
type: "file",
|
type: "file",
|
||||||
class: "file-input file-input-accent file-input-sm",
|
class: "file-input file-input-accent file-input-sm",
|
||||||
onChange: (e: Event) =>
|
onChange: (e: Event) =>
|
||||||
handleFileChange(e, device, "appBitstream2File"),
|
boardManager.handleFileChange(e, device, "appBitstream2File"),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -342,7 +316,7 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
type: "file",
|
type: "file",
|
||||||
class: "file-input file-input-info file-input-sm",
|
class: "file-input file-input-info file-input-sm",
|
||||||
onChange: (e: Event) =>
|
onChange: (e: Event) =>
|
||||||
handleFileChange(e, device, "appBitstream3File"),
|
boardManager.handleFileChange(e, device, "appBitstream3File"),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -357,8 +331,8 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
{
|
{
|
||||||
class: "btn btn-warning btn-sm",
|
class: "btn btn-warning btn-sm",
|
||||||
onClick: () =>
|
onClick: () =>
|
||||||
uploadAndDownloadBitstreams(
|
boardManager.uploadAndDownloadBitstreams(
|
||||||
device.devAddr,
|
device,
|
||||||
device.goldBitstreamFile,
|
device.goldBitstreamFile,
|
||||||
device.appBitstream1File,
|
device.appBitstream1File,
|
||||||
device.appBitstream2File,
|
device.appBitstream2File,
|
||||||
|
@ -372,9 +346,9 @@ const columns: ColumnDef<DeviceData>[] = [
|
||||||
{
|
{
|
||||||
class: "btn btn-success btn-sm",
|
class: "btn btn-success btn-sm",
|
||||||
onClick: () =>
|
onClick: () =>
|
||||||
hotresetBitstream(
|
boardManager.hotresetBitstream(
|
||||||
device.devAddr,
|
device,
|
||||||
getSelectedBitstreamNum(device.defaultBitstream),
|
boardManager.getSelectedBitstreamNum(device.defaultBitstream),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"热启动",
|
"热启动",
|
||||||
|
@ -395,7 +369,7 @@ const expanded = ref<ExpandedState>({});
|
||||||
// 创建表格实例
|
// 创建表格实例
|
||||||
const table = useVueTable({
|
const table = useVueTable({
|
||||||
get data() {
|
get data() {
|
||||||
return data.value;
|
return boardManager.boards.value;
|
||||||
},
|
},
|
||||||
columns,
|
columns,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
@ -456,110 +430,10 @@ const table = useVueTable({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
onMounted(() => {
|
||||||
// 处理文件上传
|
// 初始化数据
|
||||||
function handleFileChange(
|
boardManager.fetchBoardsData();
|
||||||
event: Event,
|
});
|
||||||
device: DeviceData,
|
|
||||||
fileKey: keyof DeviceData,
|
|
||||||
) {
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
const file = target.files?.[0];
|
|
||||||
if (file) {
|
|
||||||
(device as any)[fileKey] = file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 uploadAndDownloadBitstreams(
|
|
||||||
devAddr: string,
|
|
||||||
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 ret = await remoteUpdater.uploadBitstreams(
|
|
||||||
devAddr,
|
|
||||||
Common.toFileParameterOrNull(goldBitstream),
|
|
||||||
Common.toFileParameterOrNull(appBitstream1),
|
|
||||||
Common.toFileParameterOrNull(appBitstream2),
|
|
||||||
Common.toFileParameterOrNull(appBitstream3),
|
|
||||||
);
|
|
||||||
if (!ret) {
|
|
||||||
dialog.warn("上传比特流出错");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const ret = await remoteUpdater.downloadMultiBitstreams(
|
|
||||||
devAddr,
|
|
||||||
devPort,
|
|
||||||
getSelectedBitstreamNum(data.value[0].defaultBitstream),
|
|
||||||
);
|
|
||||||
if (ret != cnt) {
|
|
||||||
dialog.warn("固化比特流出错");
|
|
||||||
} else {
|
|
||||||
dialog.info("固化比特流成功");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
dialog.error("比特流上传错误");
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function hotresetBitstream(devAddr: string, bitstreamNum: number) {
|
|
||||||
try {
|
|
||||||
const ret = await remoteUpdater.hotResetBitstream(
|
|
||||||
devAddr,
|
|
||||||
devPort,
|
|
||||||
bitstreamNum,
|
|
||||||
);
|
|
||||||
if (ret) {
|
|
||||||
dialog.info("切换比特流成功");
|
|
||||||
} else {
|
|
||||||
dialog.error("切换比特流失败");
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
dialog.error("切换比特流失败");
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function refreshData() {
|
|
||||||
try {
|
|
||||||
const ret = await remoteUpdater.getFirmwareVersion(
|
|
||||||
data.value[0].devAddr,
|
|
||||||
devPort,
|
|
||||||
);
|
|
||||||
// 更新版本信息
|
|
||||||
if (ret) {
|
|
||||||
data.value[0].version = String(ret);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
dialog.error("获取数据失败");
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="postcss">
|
<style scoped lang="postcss">
|
||||||
|
|
|
@ -0,0 +1,288 @@
|
||||||
|
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 };
|
Loading…
Reference in New Issue