feat: 使用netsh指令设置arp
This commit is contained in:
parent
35bad4027d
commit
ba79a2093b
|
@ -84,7 +84,7 @@ public static class Arp
|
||||||
{
|
{
|
||||||
// 格式化 MAC 地址以适配不同操作系统
|
// 格式化 MAC 地址以适配不同操作系统
|
||||||
string formattedMac = FormatMacAddress(macAddress);
|
string formattedMac = FormatMacAddress(macAddress);
|
||||||
string command = GetArpAddCommand(ipAddress, formattedMac, interfaceName);
|
string command = await GetArpAddCommandAsync(ipAddress, formattedMac, interfaceName);
|
||||||
var result = await ExecuteCommandAsync(command);
|
var result = await ExecuteCommandAsync(command);
|
||||||
return result.IsSuccess;
|
return result.IsSuccess;
|
||||||
}
|
}
|
||||||
|
@ -181,13 +181,20 @@ public static class Arp
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取 ARP 添加命令
|
/// 获取 ARP 添加命令
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static string GetArpAddCommand(string ipAddress, string macAddress, string? interfaceName)
|
private static async Task<string> GetArpAddCommandAsync(string ipAddress, string macAddress, string? interfaceName)
|
||||||
{
|
{
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
return string.IsNullOrWhiteSpace(interfaceName)
|
if (!string.IsNullOrWhiteSpace(interfaceName))
|
||||||
? $"arp -s {ipAddress} {macAddress}"
|
{
|
||||||
: $"arp -s {ipAddress} {macAddress} {interfaceName}";
|
// 通过 arp -a 获取接口索引
|
||||||
|
var interfaceIdx = await GetWindowsInterfaceIndexAsync(interfaceName);
|
||||||
|
if (interfaceIdx.HasValue)
|
||||||
|
{
|
||||||
|
return $"netsh -c i i add neighbors {interfaceIdx.Value} {ipAddress} {macAddress}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $"arp -s {ipAddress} {macAddress}";
|
||||||
}
|
}
|
||||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
{
|
{
|
||||||
|
@ -207,6 +214,54 @@ public static class Arp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 Windows 接口索引
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interfaceIp">接口IP地址</param>
|
||||||
|
/// <returns>接口索引(十进制),如果未找到则返回null</returns>
|
||||||
|
private static async Task<int?> GetWindowsInterfaceIndexAsync(string interfaceIp)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await ExecuteCommandAsync("arp -a");
|
||||||
|
if (!result.IsSuccess)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var lines = result.Output.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
// 匹配接口行格式: Interface: 172.6.1.5 --- 0xa
|
||||||
|
var interfacePattern = @"Interface:\s+(\d+\.\d+\.\d+\.\d+)\s+---\s+(0x[a-fA-F0-9]+)";
|
||||||
|
var match = Regex.Match(line, interfacePattern);
|
||||||
|
|
||||||
|
if (match.Success && match.Groups[1].Value == interfaceIp)
|
||||||
|
{
|
||||||
|
// 将十六进制索引转换为十进制
|
||||||
|
var hexIndex = match.Groups[2].Value;
|
||||||
|
// 去掉 "0x" 前缀
|
||||||
|
var hexValue = hexIndex.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
|
||||||
|
? hexIndex.Substring(2)
|
||||||
|
: hexIndex;
|
||||||
|
|
||||||
|
if (int.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out int decimalIndex))
|
||||||
|
{
|
||||||
|
logger.Debug($"找到接口 {interfaceIp} 的索引: {hexIndex} -> {decimalIndex}");
|
||||||
|
return decimalIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Warn($"未找到接口 {interfaceIp} 的索引");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"获取接口 {interfaceIp} 索引失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取 ARP 删除命令
|
/// 获取 ARP 删除命令
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -478,7 +533,9 @@ public static class Arp
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增 ARP 记录
|
// 新增 ARP 记录
|
||||||
return await AddArpEntryAsync(ipAddress, formattedMac, interfaceName);
|
var ret = await AddArpEntryAsync(ipAddress, formattedMac, interfaceName);
|
||||||
|
if(!ret) logger.Error($"添加 ARP 记录失败: {ipAddress} -> {formattedMac} on {interfaceName}");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
@ -16,6 +17,8 @@ namespace server.Controllers;
|
||||||
public class DataController : ControllerBase
|
public class DataController : ControllerBase
|
||||||
{
|
{
|
||||||
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
// 固定的实验板IP,端口,MAC地址
|
||||||
|
private const string BOARD_IP = "169.254.109.0";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// [TODO:description]
|
/// [TODO:description]
|
||||||
|
@ -48,6 +51,53 @@ public class DataController : ControllerBase
|
||||||
public DateTime? BoardExpireTime { get; set; }
|
public DateTime? BoardExpireTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取本机IP地址(优先选择与实验板同网段的IP)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>本机IP地址</returns>
|
||||||
|
private IPAddress GetLocalIPAddress()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var boardIpSegments = BOARD_IP.Split('.').Take(3).ToArray();
|
||||||
|
|
||||||
|
// 优先选择与实验板IP前三段相同的IP
|
||||||
|
var sameSegmentIP = System.Net.NetworkInformation.NetworkInterface
|
||||||
|
.GetAllNetworkInterfaces()
|
||||||
|
.Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
|
||||||
|
&& nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
|
||||||
|
.SelectMany(nic => nic.GetIPProperties().UnicastAddresses)
|
||||||
|
.Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||||
|
.Select(addr => addr.Address)
|
||||||
|
.FirstOrDefault(addr =>
|
||||||
|
{
|
||||||
|
var segments = addr.ToString().Split('.');
|
||||||
|
return segments.Length == 4 &&
|
||||||
|
segments[0] == boardIpSegments[0] &&
|
||||||
|
segments[1] == boardIpSegments[1] &&
|
||||||
|
segments[2] == boardIpSegments[2];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sameSegmentIP != null)
|
||||||
|
return sameSegmentIP;
|
||||||
|
|
||||||
|
// 如果没有找到同网段的IP,返回第一个可用的IP
|
||||||
|
return System.Net.NetworkInformation.NetworkInterface
|
||||||
|
.GetAllNetworkInterfaces()
|
||||||
|
.Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
|
||||||
|
&& nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
|
||||||
|
.SelectMany(nic => nic.GetIPProperties().UnicastAddresses)
|
||||||
|
.Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||||
|
.Select(addr => addr.Address)
|
||||||
|
.FirstOrDefault() ?? IPAddress.Loopback;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, "获取本机IP地址失败");
|
||||||
|
return IPAddress.Loopback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户登录,获取 JWT 令牌
|
/// 用户登录,获取 JWT 令牌
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -228,7 +278,7 @@ public class DataController : ControllerBase
|
||||||
return NotFound("没有可用的实验板");
|
return NotFound("没有可用的实验板");
|
||||||
|
|
||||||
var boardInfo = boardOpt.Value;
|
var boardInfo = boardOpt.Value;
|
||||||
if (!(await Arp.CheckOrAddAsync(boardInfo.IpAddr, boardInfo.MacAddr)))
|
if (!(await Arp.CheckOrAddAsync(boardInfo.IpAddr, boardInfo.MacAddr, GetLocalIPAddress().ToString())))
|
||||||
{
|
{
|
||||||
logger.Error($"无法配置ARP,实验板可能会无法连接");
|
logger.Error($"无法配置ARP,实验板可能会无法连接");
|
||||||
}
|
}
|
||||||
|
@ -296,7 +346,7 @@ public class DataController : ControllerBase
|
||||||
return NotFound("未找到对应的实验板");
|
return NotFound("未找到对应的实验板");
|
||||||
|
|
||||||
var boardInfo = ret.Value.Value;
|
var boardInfo = ret.Value.Value;
|
||||||
if (!(await Arp.CheckOrAddAsync(boardInfo.IpAddr, boardInfo.MacAddr)))
|
if (!(await Arp.CheckOrAddAsync(boardInfo.IpAddr, boardInfo.MacAddr, GetLocalIPAddress().ToString())))
|
||||||
{
|
{
|
||||||
logger.Error($"无法配置ARP,实验板可能会无法连接");
|
logger.Error($"无法配置ARP,实验板可能会无法连接");
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,46 +119,7 @@ public class NetConfigController : ControllerBase
|
||||||
/// <returns>网络接口名称</returns>
|
/// <returns>网络接口名称</returns>
|
||||||
private string GetLocalNetworkInterface()
|
private string GetLocalNetworkInterface()
|
||||||
{
|
{
|
||||||
try
|
return GetLocalIPAddress().ToString();
|
||||||
{
|
|
||||||
var boardIpSegments = BOARD_IP.Split('.').Take(3).ToArray();
|
|
||||||
|
|
||||||
// 优先选择与实验板IP前三段相同的网络接口
|
|
||||||
var sameSegmentInterface = System.Net.NetworkInformation.NetworkInterface
|
|
||||||
.GetAllNetworkInterfaces()
|
|
||||||
.Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
|
|
||||||
&& nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
|
|
||||||
.FirstOrDefault(nic =>
|
|
||||||
{
|
|
||||||
var ipAddresses = nic.GetIPProperties().UnicastAddresses
|
|
||||||
.Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
||||||
.Select(addr => addr.Address);
|
|
||||||
|
|
||||||
return ipAddresses.Any(addr =>
|
|
||||||
{
|
|
||||||
var segments = addr.ToString().Split('.');
|
|
||||||
return segments.Length == 4 &&
|
|
||||||
segments[0] == boardIpSegments[0] &&
|
|
||||||
segments[1] == boardIpSegments[1] &&
|
|
||||||
segments[2] == boardIpSegments[2];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (sameSegmentInterface != null)
|
|
||||||
return sameSegmentInterface.Name;
|
|
||||||
|
|
||||||
// 如果没有找到同网段的接口,返回第一个可用的接口
|
|
||||||
return System.Net.NetworkInformation.NetworkInterface
|
|
||||||
.GetAllNetworkInterfaces()
|
|
||||||
.Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
|
|
||||||
&& nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
|
|
||||||
.FirstOrDefault()?.Name ?? "未知";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.Error(ex, "获取本机网络接口名称失败");
|
|
||||||
return "未知";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -484,6 +445,50 @@ public class NetConfigController : ControllerBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置板卡MAC地址
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="boardMac">板卡MAC地址(格式:AA:BB:CC:DD:EE:FF)</param>
|
||||||
|
/// <returns>操作结果</returns>
|
||||||
|
[HttpPost("SetBoardMAC")]
|
||||||
|
[EnableCors("Users")]
|
||||||
|
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> SetBoardMAC(string boardMac)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(boardMac))
|
||||||
|
return BadRequest("板卡MAC地址不能为空");
|
||||||
|
|
||||||
|
// 解析MAC地址
|
||||||
|
if (!TryParseMacAddress(boardMac, out var macBytes))
|
||||||
|
return BadRequest("MAC地址格式不正确,请使用格式:AA:BB:CC:DD:EE:FF");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!(await InitializeArpAsync()))
|
||||||
|
{
|
||||||
|
throw new Exception("无法配置ARP记录");
|
||||||
|
}
|
||||||
|
// 创建网络配置客户端
|
||||||
|
var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
|
||||||
|
var result = await netConfig.SetBoardMAC(macBytes);
|
||||||
|
|
||||||
|
if (!result.IsSuccessful)
|
||||||
|
{
|
||||||
|
logger.Error($"设置板卡MAC地址失败: {result.Error}");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, $"设置失败: {result.Error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(result.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, "设置板卡MAC地址时发生异常");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "设置失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置主机MAC地址
|
/// 设置主机MAC地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -8,11 +8,11 @@ static class CameraAddr
|
||||||
{
|
{
|
||||||
public const UInt32 BASE = 0x7000_0000;
|
public const UInt32 BASE = 0x7000_0000;
|
||||||
|
|
||||||
public const UInt32 STORE_ADDR = BASE + 0x12;
|
public const UInt32 DMA0_START_WRITE_ADDR = BASE + 0x0C;
|
||||||
public const UInt32 STORE_NUM = BASE + 0x13;
|
public const UInt32 DMA0_END_WRITE_ADDR = BASE + 0x0D;
|
||||||
public const UInt32 EXPECTED_VH = BASE + 0x14;
|
public const UInt32 DMA0_CAPTURE_CTRL = BASE + 0x0E; //[0]: on, 1 is on. [8]: reset, 1 is reset.
|
||||||
public const UInt32 CAPTURE_ON = BASE + 0x15;
|
public const UInt32 EXPECTED_VH = BASE + 0x0F;
|
||||||
public const UInt32 CAMERA_POWER = BASE + 0x16; //[0]: rstn, 0 is reset. [8]: power down, 1 is down.
|
public const UInt32 CAMERA_POWER = BASE + 0x10; //[0]: rstn, 0 is reset. [8]: power down, 1 is down.
|
||||||
}
|
}
|
||||||
|
|
||||||
class Camera
|
class Camera
|
||||||
|
@ -156,7 +156,7 @@ class Camera
|
||||||
|
|
||||||
public async ValueTask<Result<bool>> EnableHardwareTrans(bool isEnable)
|
public async ValueTask<Result<bool>> EnableHardwareTrans(bool isEnable)
|
||||||
{
|
{
|
||||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAPTURE_ON, Convert.ToUInt32(isEnable));
|
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.DMA0_CAPTURE_CTRL, (isEnable ? 0x00000001u : 0x00000100u));
|
||||||
if (!ret.IsSuccessful)
|
if (!ret.IsSuccessful)
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to write CAPTURE_ON to camera at {this.address}:{this.port}, error: {ret.Error}");
|
logger.Error($"Failed to write CAPTURE_ON to camera at {this.address}:{this.port}, error: {ret.Error}");
|
||||||
|
@ -361,7 +361,7 @@ class Camera
|
||||||
|
|
||||||
// 1. 配置UDP相关寄存器
|
// 1. 配置UDP相关寄存器
|
||||||
{
|
{
|
||||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.STORE_ADDR, FrameAddr);
|
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.DMA0_START_WRITE_ADDR, FrameAddr);
|
||||||
if (!ret.IsSuccessful)
|
if (!ret.IsSuccessful)
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to write STORE_ADDR: {ret.Error}");
|
logger.Error($"Failed to write STORE_ADDR: {ret.Error}");
|
||||||
|
@ -375,7 +375,7 @@ class Camera
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.STORE_NUM, frameLength);
|
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.DMA0_END_WRITE_ADDR, FrameAddr + frameLength - 1);
|
||||||
if (!ret.IsSuccessful)
|
if (!ret.IsSuccessful)
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to write STORE_NUM: {ret.Error}");
|
logger.Error($"Failed to write STORE_NUM: {ret.Error}");
|
||||||
|
@ -635,7 +635,7 @@ class Camera
|
||||||
{
|
{
|
||||||
var basicRegisters = new UInt16[][]
|
var basicRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
[0x3103, 0x03], // system clock from pad, bit[1]
|
[0x3103, 0x03], // system clock from pad, bit[1] //02
|
||||||
[0x3017, 0xff],
|
[0x3017, 0xff],
|
||||||
[0x3018, 0xff],
|
[0x3018, 0xff],
|
||||||
[0x3037, 0x13],
|
[0x3037, 0x13],
|
||||||
|
@ -750,6 +750,7 @@ class Camera
|
||||||
[0x3c04, 0x28],
|
[0x3c04, 0x28],
|
||||||
[0x3c05, 0x98],
|
[0x3c05, 0x98],
|
||||||
[0x3c06, 0x00],
|
[0x3c06, 0x00],
|
||||||
|
[0x3c07, 0x07],
|
||||||
[0x3c08, 0x00],
|
[0x3c08, 0x00],
|
||||||
[0x3c09, 0x1c],
|
[0x3c09, 0x1c],
|
||||||
[0x3c0a, 0x9c],
|
[0x3c0a, 0x9c],
|
||||||
|
@ -803,12 +804,12 @@ class Camera
|
||||||
{
|
{
|
||||||
var aecRegisters = new UInt16[][]
|
var aecRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
[0x3a0f, 0x30], // AEC控制;stable range in high
|
[0x3a0f, 0x30], // AEC控制;stable range in high //78
|
||||||
[0x3a10, 0x28], // AEC控制;stable range in low
|
[0x3a10, 0x28], // AEC控制;stable range in low //68
|
||||||
[0x3a1b, 0x30], // AEC控制;stable range out high
|
[0x3a1b, 0x30], // AEC控制;stable range out high //78
|
||||||
[0x3a1e, 0x26], // AEC控制;stable range out low
|
[0x3a1e, 0x26], // AEC控制;stable range out low //68
|
||||||
[0x3a11, 0x60], // AEC控制; fast zone high
|
[0x3a11, 0x60], // AEC控制; fast zone high //D0
|
||||||
[0x3a1f, 0x14], // AEC控制; fast zone low
|
[0x3a1f, 0x14], // AEC控制; fast zone low //40
|
||||||
[0x3b07, 0x0a] // 帧曝光模式
|
[0x3b07, 0x0a] // 帧曝光模式
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -952,7 +953,7 @@ class Camera
|
||||||
{
|
{
|
||||||
var timingRegisters = new UInt16[][]
|
var timingRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
[0x3035, 0x41], // 60fps
|
[0x3035, 0x21], // 60fps
|
||||||
[0x3036, PLL_MUX],// PLL倍频
|
[0x3036, PLL_MUX],// PLL倍频
|
||||||
[0x3c07, 0x08],
|
[0x3c07, 0x08],
|
||||||
[0x3820, 0x41], // vflip
|
[0x3820, 0x41], // vflip
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="min-h-screen bg-base-100 container mx-auto p-6 space-y-6 flex flex-row"
|
class="min-h-screen bg-base-100 container-md mx-auto p-6 space-y-6 flex flex-row"
|
||||||
>
|
>
|
||||||
<ul class="menu bg-base-200 w-56 gap-2 rounded-2xl p-5">
|
<ul class="menu bg-base-200 w-56 gap-2 rounded-2xl p-5">
|
||||||
<li id="1" @click="setActivePage">
|
<li id="1" @click="setActivePage">
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="divider divider-horizontal h-full"></div>
|
<div class="divider divider-horizontal h-full"></div>
|
||||||
<div class="card bg-base-300 w-300 rounded-2xl p-7">
|
<div class="card bg-base-300 flex-1 rounded-2xl p-7">
|
||||||
<div v-if="activePage === 1">
|
<div v-if="activePage === 1">
|
||||||
<UserInfo />
|
<UserInfo />
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue