using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using RobotNet.MapManager.Data; using RobotNet.MapManager.Services; using RobotNet.MapShares; using RobotNet.MapShares.Dtos; using RobotNet.MapShares.Enums; using RobotNet.Shares; using System.Text.Json; namespace RobotNet.MapManager.Controllers; [Route("api/[controller]")] [ApiController] [Authorize] public class EdgesController(MapEditorDbContext MapDb, LoggerController Logger) : ControllerBase { [HttpPost] [Route("")] public async Task> CreateEdge([FromBody] EdgeCreateModel model) { try { var map = await MapDb.Maps.FindAsync(model.MapId); if (map == null) return new(false, $"Không tồn tại map id = {model.MapId}"); if (Math.Sqrt(Math.Pow(model.X1 - model.X2, 2) + Math.Pow(model.Y1 - model.Y2, 2)) < map.EdgeMinLengthDefault) return new(false, "Độ dài edge quá nhỏ"); var nodes = await MapDb.Nodes.Where(n => n.MapId == model.MapId).ToListAsync(); var edges = await MapDb.Edges.Where(e => e.MapId == model.MapId && e.TrajectoryDegree == TrajectoryDegree.One).ToListAsync(); var closesStartNode = MapEditorHelper.GetClosesNode(model.X1, model.Y1, [.. nodes.Select(node => new NodeDto() { MapId = node.MapId, X = node.X, Y = node.Y, Theta = node.Theta, Actions = node.Actions, Id = node.Id, Name = node.Name, AllowedDeviationTheta = node.AllowedDeviationTheta, AllowedDeviationXy = node.AllowedDeviationXy })]); var closesEndNode = MapEditorHelper.GetClosesNode(model.X2, model.Y2, [.. nodes.Select(node => new NodeDto() { MapId = node.MapId, X = node.X, Y = node.Y, Theta = node.Theta, Actions = node.Actions, Id = node.Id, Name = node.Name, AllowedDeviationTheta = node.AllowedDeviationTheta, AllowedDeviationXy = node.AllowedDeviationXy })]); Node? startNode = await MapDb.Nodes.FindAsync(closesStartNode?.Id); Node? endNode = await MapDb.Nodes.FindAsync(closesEndNode?.Id); List RemoveEdge = []; List AddEdgeDto = []; if (startNode is null) { startNode = ServerHelper.CreateNode(map, model.X1, model.Y1); await MapDb.Nodes.AddAsync(startNode); var closesEdge = ServerHelper.GetClosesEdge(model.X1, model.Y1, nodes, edges, 0.1); if (closesEdge is not null) { var closesEdgeStartNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.StartNodeId); var closesEdgeEndNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.EndNodeId); if (closesEdgeStartNode is not null && closesEdgeEndNode is not null) { var startEdge = ServerHelper.CreateEdge(map, closesEdgeStartNode.Id, startNode.Id, TrajectoryDegree.One); var endEdge = ServerHelper.CreateEdge(map, startNode.Id, closesEdgeEndNode.Id, TrajectoryDegree.One); await MapDb.Edges.AddAsync(startEdge); await MapDb.Edges.AddAsync(endEdge); MapDb.Edges.Remove(closesEdge); edges.Remove(closesEdge); RemoveEdge.Add(closesEdge.Id); edges.Add(startEdge); edges.Add(endEdge); nodes.Add(startNode); AddEdgeDto.Add(ServerHelper.CreateEdgeDto(startEdge, closesEdgeStartNode, startNode)); AddEdgeDto.Add(ServerHelper.CreateEdgeDto(endEdge, startNode, closesEdgeEndNode)); } } } await MapDb.SaveChangesAsync(); if (endNode is null) { endNode = ServerHelper.CreateNode(map, model.X2, model.Y2); await MapDb.Nodes.AddAsync(endNode); var closesEdge = ServerHelper.GetClosesEdge(model.X2, model.Y2, nodes, edges, 0.1); if (closesEdge is not null) { var closesEdgeStartNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.StartNodeId); var closesEdgeEndNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.EndNodeId); if (closesEdgeStartNode is not null && closesEdgeEndNode is not null) { var startEdge = ServerHelper.CreateEdge(map, closesEdgeStartNode.Id, endNode.Id, TrajectoryDegree.One); var endEdge = ServerHelper.CreateEdge(map, endNode.Id, closesEdgeEndNode.Id, TrajectoryDegree.One); await MapDb.Edges.AddAsync(startEdge); await MapDb.Edges.AddAsync(endEdge); MapDb.Edges.Remove(closesEdge); RemoveEdge.Add(closesEdge.Id); AddEdgeDto.Add(ServerHelper.CreateEdgeDto(startEdge, closesEdgeStartNode, endNode)); AddEdgeDto.Add(ServerHelper.CreateEdgeDto(endEdge, endNode, closesEdgeEndNode)); } } } var edge = ServerHelper.CreateEdge(map, startNode.Id, endNode.Id, model.TrajectoryDegree, model.ControlPoint1X, model.ControlPoint1Y, model.ControlPoint2X, model.ControlPoint2Y); await MapDb.Edges.AddAsync(edge); await MapDb.SaveChangesAsync(); AddEdgeDto.Add(ServerHelper.CreateEdgeDto(edge, startNode, endNode)); return new(true) { Data = new EdgeCreateDto() { EdgesDto = AddEdgeDto, RemoveEdge = RemoveEdge, } }; } catch (Exception ex) { Logger.Warning($"CreateEdge: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"CreateEdge: Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpDelete] [Route("{id}")] public async Task DeleteEdge(Guid id) { using var transaction = await MapDb.Database.BeginTransactionAsync(); try { var edge = await MapDb.Edges.FindAsync(id); if (edge == null) return new(false, $"Không tồn tại edge id = {id}"); MapDb.Edges.Remove(edge); if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.StartNodeId || e.EndNodeId == edge.StartNodeId) && e.Id != edge.Id)) { var node = await MapDb.Nodes.FindAsync(edge.StartNodeId); if (node != null) { var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id); if (element is not null) MapDb.Elements.Remove(element); MapDb.Nodes.Remove(node); } } if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.EndNodeId || e.EndNodeId == edge.EndNodeId) && e.Id != edge.Id)) { var node = await MapDb.Nodes.FindAsync(edge.EndNodeId); if (node != null) { var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id); if (element is not null) MapDb.Elements.Remove(element); MapDb.Nodes.Remove(node); } } await MapDb.SaveChangesAsync(); await transaction.CommitAsync(); return new(true); } catch (Exception ex) { await transaction.RollbackAsync(); Logger.Warning($"DeleteEdge {id}: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"DeleteEdge {id}: Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpDelete] [Route("")] public async Task DeleteEdges([FromBody] IEnumerable DeleteEdgesId) { try { List deleteEdges = []; List deleteNodes = []; foreach (var edgeId in DeleteEdgesId) { var edge = await MapDb.Edges.FindAsync(edgeId); if (edge == null) continue; MapDb.Edges.Remove(edge); if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.StartNodeId || e.EndNodeId == edge.StartNodeId) && e.Id != edge.Id)) { var node = await MapDb.Nodes.FindAsync(edge.StartNodeId); if (node != null) { var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id); if (element is not null) MapDb.Elements.Remove(element); MapDb.Nodes.Remove(node); } } if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.EndNodeId || e.EndNodeId == edge.EndNodeId) && e.Id != edge.Id)) { var node = await MapDb.Nodes.FindAsync(edge.EndNodeId); if (node != null) { var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id); if (element is not null) MapDb.Elements.Remove(element); MapDb.Nodes.Remove(node); } } await MapDb.SaveChangesAsync(); } return new(true); } catch (Exception ex) { Logger.Warning($"DeleteEdges: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"DeleteEdges: Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpPut] [Route("")] public async Task UpdateEdge([FromBody] EdgeUpdateModel model) { try { var edge = await MapDb.Edges.FindAsync(model.Id); if (edge == null) return new(false, $"Không tồn tại edge id = {model.Id}"); edge.MaxSpeed = model.MaxSpeed; edge.MaxHeight = model.MaxHeight; edge.MinHeight = model.MinHeight; edge.ControlPoint1X = model.ControlPoint1X; edge.ControlPoint1Y = model.ControlPoint1Y; edge.ControlPoint2X = model.ControlPoint2X; edge.ControlPoint2Y = model.ControlPoint2Y; edge.DirectionAllowed = model.DirectionAllowed; edge.RotationAllowed = model.RotationAllowed; edge.MaxRotationSpeed = model.MaxRotationSpeed; edge.Actions = JsonSerializer.Serialize(model.Actions ?? []); edge.AllowedDeviationXy = model.AllowedDeviationXy; edge.AllowedDeviationTheta = model.AllowedDeviationTheta; await MapDb.SaveChangesAsync(); return new(true); } catch (Exception ex) { Logger.Warning($"UpdateEdge: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"UpdateEdge: Hệ thống có lỗi xảy ra - {ex.Message}"); } } }