From 9af2d3e87ea579999346402df6e3904b0cbf4b53 Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Fri, 18 Jul 2025 13:16:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E9=9D=99=E6=80=81arp?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=9A=E4=BF=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/ArpClient.cs | 32 ++++- server/src/Controllers/DataController.cs | 75 ++++++++++- server/src/Controllers/NetConfigController.cs | 44 +++++++ server/src/Peripherals/NetConfigClient.cs | 101 ++++++++------- src/APIClient.ts | 118 ++++++++++++++++++ src/views/User/AddBoardDialog.vue | 77 ++++++++---- 6 files changed, 372 insertions(+), 75 deletions(-) diff --git a/server/src/ArpClient.cs b/server/src/ArpClient.cs index 6398670..4172ac9 100644 --- a/server/src/ArpClient.cs +++ b/server/src/ArpClient.cs @@ -433,8 +433,38 @@ public static class Arp return Environment.UserName == "root" || (Environment.GetEnvironmentVariable("USER") == "root"); } } -} + /// + /// 检查指定 IP 是否存在对应的 MAC,如果不存在则删除原有 ARP 记录并新增 + /// + /// IP 地址 + /// MAC 地址 + /// 网络接口名称(可选) + /// 是否成功 + public static async Task CheckOrAddAsync(string ipAddress, string macAddress, string? interfaceName = null) + { + if (string.IsNullOrWhiteSpace(ipAddress)) + throw new ArgumentException("IP 地址不能为空", nameof(ipAddress)); + if (string.IsNullOrWhiteSpace(macAddress)) + throw new ArgumentException("MAC 地址不能为空", nameof(macAddress)); + + var entry = await GetArpEntryAsync(ipAddress); + if (entry != null && string.Equals(entry.MacAddress, macAddress, StringComparison.OrdinalIgnoreCase)) + { + // 已存在且 MAC 匹配,无需操作 + return true; + } + + // 若存在但 MAC 不匹配,先删除 + if (entry != null) + { + await DeleteArpEntryAsync(ipAddress, interfaceName); + } + + // 新增 ARP 记录 + return await AddArpEntryAsync(ipAddress, macAddress, interfaceName); + } +} /// /// ARP 记录条目 /// diff --git a/server/src/Controllers/DataController.cs b/server/src/Controllers/DataController.cs index f34fe19..15a00e3 100644 --- a/server/src/Controllers/DataController.cs +++ b/server/src/Controllers/DataController.cs @@ -207,7 +207,7 @@ public class DataController : ControllerBase [ProducesResponseType(typeof(Database.Board), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public IActionResult GetAvailableBoard(int durationHours = 1) + public async ValueTask GetAvailableBoard(int durationHours = 1) { try { @@ -227,7 +227,13 @@ public class DataController : ControllerBase if (!boardOpt.HasValue) return NotFound("没有可用的实验板"); - return Ok(boardOpt.Value); + var boardInfo = boardOpt.Value; + if (!(await Arp.CheckOrAddAsync(boardInfo.IpAddr, boardInfo.MacAddr))) + { + logger.Error($"无法配置ARP,实验板可能会无法连接"); + } + + return Ok(boardInfo); } catch (Exception ex) { @@ -278,7 +284,7 @@ public class DataController : ControllerBase [ProducesResponseType(typeof(Database.Board), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public IActionResult GetBoardByID(Guid id) + public async Task GetBoardByID(Guid id) { try { @@ -288,7 +294,14 @@ public class DataController : ControllerBase return StatusCode(StatusCodes.Status500InternalServerError, "数据库操作失败"); if (!ret.Value.HasValue) return NotFound("未找到对应的实验板"); - return Ok(ret.Value.Value); + + var boardInfo = ret.Value.Value; + if (!(await Arp.CheckOrAddAsync(boardInfo.IpAddr, boardInfo.MacAddr))) + { + logger.Error($"无法配置ARP,实验板可能会无法连接"); + } + + return Ok(boardInfo); } catch (Exception ex) { @@ -372,5 +385,59 @@ public class DataController : ControllerBase return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试"); } } + + /// + /// 更新板卡名称(管理员权限) + /// + [Authorize("Admin")] + [HttpPost("UpdateBoardName")] + [EnableCors("Users")] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public IActionResult UpdateBoardName(Guid boardId, string newName) + { + if (boardId == Guid.Empty) + return BadRequest("板子Guid不能为空"); + if (string.IsNullOrWhiteSpace(newName)) + return BadRequest("新名称不能为空"); + try + { + using var db = new Database.AppDataConnection(); + var result = db.UpdateBoardName(boardId, newName); + return Ok(result); + } + catch (Exception ex) + { + logger.Error(ex, "更新板卡名称时发生异常"); + return StatusCode(StatusCodes.Status500InternalServerError, "更新失败,请稍后重试"); + } + } + + /// + /// 更新板卡状态(管理员权限) + /// + [Authorize("Admin")] + [HttpPost("UpdateBoardStatus")] + [EnableCors("Users")] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public IActionResult UpdateBoardStatus(Guid boardId, Database.Board.BoardStatus newStatus) + { + if (boardId == Guid.Empty) + return BadRequest("板子Guid不能为空"); + try + { + using var db = new Database.AppDataConnection(); + var result = db.UpdateBoardStatus(boardId, newStatus); + return Ok(result); + } + catch (Exception ex) + { + logger.Error(ex, "更新板卡状态时发生异常"); + return StatusCode(StatusCodes.Status500InternalServerError, "更新失败,请稍后重试"); + } + } } diff --git a/server/src/Controllers/NetConfigController.cs b/server/src/Controllers/NetConfigController.cs index 451b31f..e62313a 100644 --- a/server/src/Controllers/NetConfigController.cs +++ b/server/src/Controllers/NetConfigController.cs @@ -33,6 +33,10 @@ public class NetConfigController : ControllerBase try { var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.GetHostIP(); if (!result.IsSuccessful) @@ -63,6 +67,10 @@ public class NetConfigController : ControllerBase try { var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.GetBoardIP(); if (!result.IsSuccessful) @@ -93,6 +101,10 @@ public class NetConfigController : ControllerBase try { var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.GetHostMAC(); if (!result.IsSuccessful) @@ -123,6 +135,10 @@ public class NetConfigController : ControllerBase try { var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.GetBoardMAC(); if (!result.IsSuccessful) @@ -153,6 +169,10 @@ public class NetConfigController : ControllerBase try { var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var hostIPResult = await netConfig.GetHostIP(); var boardIPResult = await netConfig.GetBoardIP(); @@ -237,6 +257,10 @@ public class NetConfigController : ControllerBase { // 创建网络配置客户端 var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.SetHostIP(hostIpAddress); if (!result.IsSuccessful) @@ -276,6 +300,10 @@ public class NetConfigController : ControllerBase { // 创建网络配置客户端 var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.SetBoardIP(newIpAddress); if (!result.IsSuccessful) @@ -316,6 +344,10 @@ public class NetConfigController : ControllerBase { // 创建网络配置客户端 var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.SetHostMAC(macBytes); if (!result.IsSuccessful) @@ -367,6 +399,10 @@ public class NetConfigController : ControllerBase return StatusCode(StatusCodes.Status500InternalServerError, "无法获取本机IP地址"); var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.SetHostIP(ip); if (!result.IsSuccessful) @@ -411,6 +447,10 @@ public class NetConfigController : ControllerBase // 创建网络配置客户端 var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.SetHostMAC(macBytes); if (!result.IsSuccessful) @@ -451,6 +491,10 @@ public class NetConfigController : ControllerBase { // 创建网络配置客户端 var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0); + if (!(await netConfig.Init())) + { + throw new Exception($"无法配置ARP"); + } var result = await netConfig.SetBoardMAC(macBytes); if (!result.IsSuccessful) diff --git a/server/src/Peripherals/NetConfigClient.cs b/server/src/Peripherals/NetConfigClient.cs index 3ed4a6c..9115a68 100644 --- a/server/src/Peripherals/NetConfigClient.cs +++ b/server/src/Peripherals/NetConfigClient.cs @@ -26,6 +26,8 @@ public class NetConfig readonly string address; private IPEndPoint ep; + const string DEFAULT_BOARD_MAC = "12:34:56:78:9a:bc"; + /// /// Initialize NetConfig client /// @@ -44,6 +46,15 @@ public class NetConfig this.timeout = timeout; } + /// + /// [TODO:description] + /// + /// [TODO:return] + public async ValueTask Init() + { + return await Arp.CheckOrAddAsync(this.address, DEFAULT_BOARD_MAC); + } + /// /// Set host IP address /// @@ -55,11 +66,11 @@ public class NetConfig MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ipBytes = ip.GetAddressBytes(); @@ -106,11 +117,11 @@ public class NetConfig MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ipBytes = ip.GetAddressBytes(); @@ -160,13 +171,13 @@ public class NetConfig // 清除UDP服务器接收缓冲区 MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); - + // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_MAC, macAddress, this.timeout); if (!ret.IsSuccessful) @@ -214,13 +225,13 @@ public class NetConfig // 清除UDP服务器接收缓冲区 MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); - + // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_MAC, macAddress, this.timeout); if (!ret.IsSuccessful) @@ -262,13 +273,13 @@ public class NetConfig { // 清除UDP服务器接收缓冲区 MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); - + // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_IP, this.timeout); if (!ret.IsSuccessful) @@ -296,13 +307,13 @@ public class NetConfig { // 清除UDP服务器接收缓冲区 MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); - + // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_IP, this.timeout); if (!ret.IsSuccessful) @@ -332,11 +343,11 @@ public class NetConfig MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_MAC, this.timeout); if (!ret.IsSuccessful) @@ -364,13 +375,13 @@ public class NetConfig { // 清除UDP服务器接收缓冲区 MsgBus.UDPServer.ClearUDPData(this.address, this.taskID); - + // 刷新ARP - var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); - if (!refrshRet) - { - logger.Warn($"Refrash Arp failed, but maybe not a big deal."); - } + // var refrshRet = await Arp.UpdateArpEntryByPingAsync(this.address); + // if (!refrshRet) + // { + // logger.Warn($"Refrash Arp failed, but maybe not a big deal."); + // } var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_MAC, this.timeout); if (!ret.IsSuccessful) diff --git a/src/APIClient.ts b/src/APIClient.ts index 3b49e6d..4f29235 100644 --- a/src/APIClient.ts +++ b/src/APIClient.ts @@ -1278,6 +1278,124 @@ export class DataClient { } return Promise.resolve(null as any); } + + /** + * 更新板卡名称(管理员权限) + * @param boardId (optional) + * @param newName (optional) + */ + updateBoardName(boardId: string | undefined, newName: string | undefined): Promise { + let url_ = this.baseUrl + "/api/Data/UpdateBoardName?"; + if (boardId === null) + throw new Error("The parameter 'boardId' cannot be null."); + else if (boardId !== undefined) + url_ += "boardId=" + encodeURIComponent("" + boardId) + "&"; + if (newName === null) + throw new Error("The parameter 'newName' cannot be null."); + else if (newName !== undefined) + url_ += "newName=" + encodeURIComponent("" + newName) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processUpdateBoardName(_response); + }); + } + + protected processUpdateBoardName(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 !== undefined ? resultData200 : null; + + return result200; + }); + } else if (status === 400) { + return response.text().then((_responseText) => { + let result400: any = null; + let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result400 = ProblemDetails.fromJS(resultData400); + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("A server side error occurred.", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null as any); + } + + /** + * 更新板卡状态(管理员权限) + * @param boardId (optional) + * @param newStatus (optional) + */ + updateBoardStatus(boardId: string | undefined, newStatus: BoardStatus | undefined): Promise { + let url_ = this.baseUrl + "/api/Data/UpdateBoardStatus?"; + if (boardId === null) + throw new Error("The parameter 'boardId' cannot be null."); + else if (boardId !== undefined) + url_ += "boardId=" + encodeURIComponent("" + boardId) + "&"; + if (newStatus === null) + throw new Error("The parameter 'newStatus' cannot be null."); + else if (newStatus !== undefined) + url_ += "newStatus=" + encodeURIComponent("" + newStatus) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processUpdateBoardStatus(_response); + }); + } + + protected processUpdateBoardStatus(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 !== undefined ? resultData200 : null; + + return result200; + }); + } else if (status === 400) { + return response.text().then((_responseText) => { + let result400: any = null; + let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result400 = ProblemDetails.fromJS(resultData400); + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + return throwException("A server side error occurred.", status, _responseText, _headers); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null as any); + } } export class DDSClient { diff --git a/src/views/User/AddBoardDialog.vue b/src/views/User/AddBoardDialog.vue index f5863f9..1bb9192 100644 --- a/src/views/User/AddBoardDialog.vue +++ b/src/views/User/AddBoardDialog.vue @@ -134,21 +134,29 @@

网络配置信息:

-
主机IP: {{ networkConfig.hostIP }}
-
板卡IP: {{ networkConfig.boardIP }}
-
主机MAC: {{ networkConfig.hostMAC }}
-
板卡MAC: {{ networkConfig.boardMAC }}
+
+ 主机IP: + {{ networkConfig.hostIP }} +
+
+ 板卡IP: + {{ networkConfig.boardIP }} +
+
+ 主机MAC: + {{ networkConfig.hostMAC }} +
+
+ 板卡MAC: + {{ networkConfig.boardMAC }} +
@@ -166,7 +174,9 @@ import { ref, reactive, watch } from "vue"; import { AuthManager } from "../../utils/AuthManager"; import { useAlertStore } from "../../components/Alert"; -import type { NetworkConfigDto } from "../../APIClient"; +import { BoardStatus, type NetworkConfigDto } from "../../APIClient"; +import { useRequiredInjection } from "@/utils/Common"; +import { useBoardManager } from "@/utils/BoardManager"; // Props 和 Emits interface Props { @@ -184,8 +194,12 @@ const emit = defineEmits(); // 使用 Alert const alertStore = useAlertStore(); +const boardManager = useRequiredInjection(useBoardManager); + // 当前步骤 -const currentStep = ref<'input' | 'pairing' | 'configuring' | 'result'>('input'); +const currentStep = ref<"input" | "pairing" | "configuring" | "result">( + "input", +); // 表单数据 const form = reactive({ @@ -231,7 +245,7 @@ function validateForm(): boolean { function resetForm() { form.name = "Board1"; errors.name = ""; - currentStep.value = 'input'; + currentStep.value = "input"; addedBoardId.value = ""; networkConfig.value = null; } @@ -255,13 +269,13 @@ async function handleSubmit() { try { // 通过 AuthManager 获取认证的 DataClient const dataClient = AuthManager.createAuthenticatedDataClient(); - + // 添加板卡到数据库 const boardId = await dataClient.addBoard(form.name.trim()); - + if (boardId) { addedBoardId.value = boardId; - currentStep.value = 'pairing'; + currentStep.value = "pairing"; alertStore?.success("板卡添加成功,请开启配对模式"); } else { alertStore?.error("板卡添加失败"); @@ -281,10 +295,10 @@ async function handleCancelPairing() { try { // 通过 AuthManager 获取认证的 DataClient const dataClient = AuthManager.createAuthenticatedDataClient(); - + // 删除添加的板卡 await dataClient.deleteBoard(addedBoardId.value); - + alertStore?.info("已取消添加实验板"); emit("update:visible", false); resetForm(); @@ -299,7 +313,7 @@ async function handlePairingConfirm() { if (!addedBoardId.value) return; isConfiguring.value = true; - currentStep.value = 'configuring'; + currentStep.value = "configuring"; try { // 通过 AuthManager 获取认证的客户端 @@ -308,7 +322,7 @@ async function handlePairingConfirm() { // 获取数据库中对应分配的板卡信息 const boardInfo = await dataClient.getBoardByID(addedBoardId.value); - + if (!boardInfo) { throw new Error("无法获取板卡信息"); } @@ -321,21 +335,34 @@ async function handlePairingConfirm() { await netConfigClient.setBoardIP(boardInfo.ipAddr); await netConfigClient.setBoardMAC(boardInfo.macAddr); + // 更新板卡状态为可用 + if ( + (await dataClient.updateBoardStatus( + boardInfo.id, + BoardStatus.Available, + )) != 1 + ) { + throw new Error("无法更新板卡状态"); + } + + if (!(await boardManager.getAllBoards()).success) { + alertStore?.error("无法获取板卡列表"); + } + // 获取实验板网络信息 const networkInfo = await netConfigClient.getNetworkConfig(); - + if (networkInfo) { networkConfig.value = networkInfo; - currentStep.value = 'result'; + currentStep.value = "result"; alertStore?.success("实验板配置成功"); } else { throw new Error("无法获取网络配置信息"); } - } catch (error) { console.error("配置实验板失败:", error); alertStore?.error("配置实验板失败"); - + // 配置失败,删除数据库中的板卡信息 try { const dataClient = AuthManager.createAuthenticatedDataClient(); @@ -343,9 +370,9 @@ async function handlePairingConfirm() { } catch (deleteError) { console.error("删除板卡失败:", deleteError); } - + // 返回输入步骤 - currentStep.value = 'input'; + currentStep.value = "input"; } finally { isConfiguring.value = false; }