feat: 后端添加获取空闲实验板,继续修改前端界面使其更加合理
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@@ -192,6 +191,45 @@ public class DataController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个空闲的实验板(普通用户权限)
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
[HttpGet("GetAvailableBoard")]
|
||||
[EnableCors("Users")]
|
||||
[ProducesResponseType(typeof(Database.Board), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public IActionResult GetAvailableBoard()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var db = new Database.AppDataConnection();
|
||||
var boardOpt = db.GetAvailableBoard();
|
||||
if (!boardOpt.HasValue)
|
||||
return NotFound("没有可用的实验板");
|
||||
|
||||
// 绑定用户与实验板
|
||||
var userName = User.Identity?.Name;
|
||||
if (string.IsNullOrEmpty(userName))
|
||||
return Unauthorized("未找到用户名信息");
|
||||
|
||||
var userRet = db.GetUserByName(userName);
|
||||
if (!userRet.IsSuccessful || !userRet.Value.HasValue)
|
||||
return BadRequest("用户不存在");
|
||||
|
||||
var user = userRet.Value.Value;
|
||||
db.BindUserToBoard(user.ID, boardOpt.Value.ID);
|
||||
|
||||
return Ok(boardOpt.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "获取空闲实验板时发生异常");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增板子(管理员权限)
|
||||
/// </summary>
|
||||
|
@@ -29,35 +29,35 @@ public class User
|
||||
public required string EMail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 用户的密码(应该进行哈希处理)
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public required string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 用户权限等级
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public required UserPermission Permission { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 绑定的实验板ID,如果未绑定则为空
|
||||
/// </summary>
|
||||
[Nullable]
|
||||
public Guid BoardID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 用户权限枚举
|
||||
/// </summary>
|
||||
public enum UserPermission
|
||||
{
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 管理员权限,可以管理用户和实验板
|
||||
/// </summary>
|
||||
Admin,
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 普通用户权限,只能使用实验板
|
||||
/// </summary>
|
||||
Normal,
|
||||
}
|
||||
@@ -81,41 +81,41 @@ public class Board
|
||||
public required string BoardName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// FPGA 板子的IP地址
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public required string IpAddr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// FPGA 板子的通信端口
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public required int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// FPGA 板子的当前状态
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public required BoardStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// FPGA 板子的固件版本号
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public string FirmVersion { get; set; } = "1.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// FPGA 板子状态枚举
|
||||
/// </summary>
|
||||
public enum BoardStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 繁忙状态,正在被用户使用
|
||||
/// </summary>
|
||||
Busy,
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 可用状态,可以被分配给用户
|
||||
/// </summary>
|
||||
Available,
|
||||
}
|
||||
@@ -140,6 +140,7 @@ public class AppDataConnection : DataConnection
|
||||
{
|
||||
if (!Path.Exists(DATABASE_FILEPATH))
|
||||
{
|
||||
logger.Info($"数据库文件不存在,正在创建新数据库: {DATABASE_FILEPATH}");
|
||||
LinqToDB.DataProvider.SQLite.SQLiteTools.CreateDatabase(DATABASE_FILEPATH);
|
||||
this.CreateAllTables();
|
||||
var user = new User()
|
||||
@@ -150,6 +151,11 @@ public class AppDataConnection : DataConnection
|
||||
Permission = Database.User.UserPermission.Admin,
|
||||
};
|
||||
this.Insert(user);
|
||||
logger.Info("默认管理员用户已创建");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"数据库连接已建立: {DATABASE_FILEPATH}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +165,10 @@ public class AppDataConnection : DataConnection
|
||||
/// </summary>
|
||||
public void CreateAllTables()
|
||||
{
|
||||
logger.Info("正在创建数据库表...");
|
||||
this.CreateTable<User>();
|
||||
this.CreateTable<Board>();
|
||||
logger.Info("数据库表创建完成");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -168,16 +176,18 @@ public class AppDataConnection : DataConnection
|
||||
/// </summary>
|
||||
public void DropAllTables()
|
||||
{
|
||||
logger.Warn("正在删除所有数据库表...");
|
||||
this.DropTable<User>();
|
||||
this.DropTable<Board>();
|
||||
logger.Warn("所有数据库表已删除");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个新的用户到数据库
|
||||
/// </summary>
|
||||
/// <param name="name">用户的名称</param>
|
||||
/// <param name="email">[TODO:parameter]</param>
|
||||
/// <param name="password">[TODO:parameter]</param>
|
||||
/// <param name="email">用户的电子邮箱地址</param>
|
||||
/// <param name="password">用户的密码</param>
|
||||
/// <returns>插入的记录数</returns>
|
||||
public int AddUser(string name, string email, string password)
|
||||
{
|
||||
@@ -188,63 +198,67 @@ public class AppDataConnection : DataConnection
|
||||
Password = password,
|
||||
Permission = Database.User.UserPermission.Normal,
|
||||
};
|
||||
return this.Insert(user);
|
||||
var result = this.Insert(user);
|
||||
logger.Info($"新用户已添加: {name} ({email})");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 根据用户名获取用户信息
|
||||
/// </summary>
|
||||
/// <param name="name">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="name">用户名</param>
|
||||
/// <returns>包含用户信息的结果,如果未找到或出错则返回相应状态</returns>
|
||||
public Result<Optional<User>> GetUserByName(string name)
|
||||
{
|
||||
var user = this.User.Where((user) => user.Name == name).ToArray();
|
||||
|
||||
if (user.Length > 1)
|
||||
{
|
||||
logger.Error($"TODO");
|
||||
return new(new Exception($"TODO"));
|
||||
logger.Error($"数据库中存在多个同名用户: {name}");
|
||||
return new(new Exception($"数据库中存在多个同名用户: {name}"));
|
||||
}
|
||||
|
||||
if (user.Length == 0)
|
||||
{
|
||||
logger.Info($"TODO");
|
||||
logger.Info($"未找到用户: {name}");
|
||||
return new(Optional<User>.None);
|
||||
}
|
||||
|
||||
logger.Debug($"成功获取用户信息: {name}");
|
||||
return new(user[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 根据电子邮箱获取用户信息
|
||||
/// </summary>
|
||||
/// <param name="email">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="email">用户的电子邮箱地址</param>
|
||||
/// <returns>包含用户信息的结果,如果未找到或出错则返回相应状态</returns>
|
||||
public Result<Optional<User>> GetUserByEMail(string email)
|
||||
{
|
||||
var user = this.User.Where((user) => user.EMail == email).ToArray();
|
||||
|
||||
if (user.Length > 1)
|
||||
{
|
||||
logger.Error($"TODO");
|
||||
return new(new Exception($"TODO"));
|
||||
logger.Error($"数据库中存在多个相同邮箱的用户: {email}");
|
||||
return new(new Exception($"数据库中存在多个相同邮箱的用户: {email}"));
|
||||
}
|
||||
|
||||
if (user.Length == 0)
|
||||
{
|
||||
logger.Info($"TODO");
|
||||
logger.Info($"未找到邮箱对应的用户: {email}");
|
||||
return new(Optional<User>.None);
|
||||
}
|
||||
|
||||
logger.Debug($"成功获取用户信息: {email}");
|
||||
return new(user[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 验证用户密码
|
||||
/// </summary>
|
||||
/// <param name="name">[TODO:parameter]</param>
|
||||
/// <param name="password">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="name">用户名</param>
|
||||
/// <param name="password">用户密码</param>
|
||||
/// <returns>如果密码正确返回用户信息,否则返回空</returns>
|
||||
public Result<Optional<User>> CheckUserPassword(string name, string password)
|
||||
{
|
||||
var ret = this.GetUserByName(name);
|
||||
@@ -256,16 +270,40 @@ public class AppDataConnection : DataConnection
|
||||
|
||||
var user = ret.Value.Value;
|
||||
|
||||
if (user.Password == password) return new(user);
|
||||
else return new(Optional<User>.None);
|
||||
if (user.Password == password)
|
||||
{
|
||||
logger.Info($"用户 {name} 密码验证成功");
|
||||
return new(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn($"用户 {name} 密码验证失败");
|
||||
return new(Optional<User>.None);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定用户与实验板
|
||||
/// </summary>
|
||||
/// <param name="userId">用户的唯一标识符</param>
|
||||
/// <param name="boardId">实验板的唯一标识符</param>
|
||||
/// <returns>更新的记录数</returns>
|
||||
public int BindUserToBoard(Guid userId, Guid boardId)
|
||||
{
|
||||
var result = this.User
|
||||
.Where(u => u.ID == userId)
|
||||
.Set(u => u.BoardID, boardId)
|
||||
.Update();
|
||||
logger.Info($"用户 {userId} 已绑定到实验板 {boardId}");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一块新的 FPGA 板子到数据库
|
||||
/// </summary>
|
||||
/// <param name="name">FPGA 板子的名称</param>
|
||||
/// <param name="ipAddr">[TODO:Param]</param>
|
||||
/// <param name="port">[TODO:Param]</param>
|
||||
/// <param name="ipAddr">FPGA 板子的IP地址</param>
|
||||
/// <param name="port">FPGA 板子的通信端口</param>
|
||||
/// <returns>插入的记录数</returns>
|
||||
public int AddBoard(string name, string ipAddr, int port)
|
||||
{
|
||||
@@ -276,51 +314,59 @@ public class AppDataConnection : DataConnection
|
||||
Port = port,
|
||||
Status = Database.Board.BoardStatus.Available,
|
||||
};
|
||||
return this.Insert(board);
|
||||
var result = this.Insert(board);
|
||||
logger.Info($"新实验板已添加: {name} ({ipAddr}:{port})");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 根据名称删除实验板
|
||||
/// </summary>
|
||||
/// <param name="name">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="name">实验板的名称</param>
|
||||
/// <returns>删除的记录数</returns>
|
||||
public int DeleteBoardByName(string name)
|
||||
{
|
||||
return this.Board.Where(board => board.BoardName == name).Delete();
|
||||
var result = this.Board.Where(board => board.BoardName == name).Delete();
|
||||
logger.Info($"实验板已删除: {name},删除记录数: {result}");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 根据ID删除实验板
|
||||
/// </summary>
|
||||
/// <param name="id">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <param name="id">实验板的唯一标识符</param>
|
||||
/// <returns>删除的记录数</returns>
|
||||
public int DeleteBoardByID(Guid id)
|
||||
{
|
||||
return this.Board.Where(board => board.ID == id).Delete();
|
||||
var result = this.Board.Where(board => board.ID == id).Delete();
|
||||
logger.Info($"实验板已删除: {id},删除记录数: {result}");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 获取所有实验板信息
|
||||
/// </summary>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <returns>所有实验板的数组</returns>
|
||||
public Board[] GetAllBoard()
|
||||
{
|
||||
return this.Board.ToArray();
|
||||
var boards = this.Board.ToArray();
|
||||
logger.Debug($"获取所有实验板,共 {boards.Length} 块");
|
||||
return boards;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [TODO:description]
|
||||
/// 获取一块可用的实验板并将其状态设置为繁忙
|
||||
/// </summary>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
/// <returns>可用的实验板,如果没有可用的板子则返回空</returns>
|
||||
public Optional<Board> GetAvailableBoard()
|
||||
{
|
||||
var boards = this.Board.Where(
|
||||
(board) => board.Status == Database.Board.BoardStatus.Available
|
||||
).ToArray();
|
||||
|
||||
if (boards.Length < 0)
|
||||
if (boards.Length == 0)
|
||||
{
|
||||
logger.Warn($"TODO");
|
||||
logger.Warn("没有可用的实验板");
|
||||
return new(null);
|
||||
}
|
||||
else
|
||||
@@ -331,6 +377,7 @@ public class AppDataConnection : DataConnection
|
||||
.Where(target => target.ID == board.ID)
|
||||
.Set(target => target.Status, board.Status)
|
||||
.Update();
|
||||
logger.Info($"实验板 {board.BoardName} ({board.ID}) 已分配,状态更新为繁忙");
|
||||
return new(board);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user