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.Models; using RobotNet.MapShares.Property; using RobotNet.Shares; using Serialize.Linq.Serializers; using System.Linq.Expressions; namespace RobotNet.MapManager.Controllers; [Route("api/[controller]")] [ApiController] [Authorize] public class ScriptElementsController(MapEditorDbContext MapDb, LoggerController Logger) : ControllerBase { private static readonly ExpressionSerializer expressionSerializer; static ScriptElementsController() { var jss = new Serialize.Linq.Serializers.JsonSerializer(); expressionSerializer = new ExpressionSerializer(jss); expressionSerializer.AddKnownType(typeof(Script.Expressions.ElementProperties)); } [HttpPost] public async Task>> GetElementsWithCondition([FromBody] ElementExpressionModel model) { try { var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == model.MapName); if (map is null) return new(false, $"Không tồn tại map tên = {model.MapName}"); var elModel = await MapDb.ElementModels.FirstOrDefaultAsync(m => m.MapId == map.Id && m.Name == model.ModelName); if (elModel is null) return new(false, $"Không tồn tại element model tên = {model.ModelName}"); var modelProperties = System.Text.Json.JsonSerializer.Deserialize>(elModel.Content, JsonOptionExtends.Read); if (modelProperties is null || modelProperties.Count == 0) return new(false, $"Không tồn tại property nào trong element model tên = {model.ModelName}"); var expr = expressionSerializer.DeserializeText(model.Expression); var lambda = (Expression>)expr; // Compile và chạy: var func = lambda.Compile(); var elements = await MapDb.Elements.Where(e => e.MapId == map.Id && e.ModelId == elModel.Id).ToListAsync(); List elementSatisfies = []; foreach (var element in elements) { var properties = MapManagerExtensions.GetElementProperties(element.IsOpen, element.Content); if (func.Invoke(properties)) { var elNode = await MapDb.Nodes.FindAsync(element.NodeId); if (elNode is null) continue; // Bỏ qua nếu không tìm thấy node elementSatisfies.Add(new ElementDto() { Id = element.Id, Name = element.Name, MapId = element.MapId, IsOpen = element.IsOpen, NodeId = element.NodeId, OffsetX = element.OffsetX, OffsetY = element.OffsetY, ModelId = element.ModelId, Content = element.Content, NodeName = elNode.Name, ModelName = elModel.Name, X = elNode.X, Y = elNode.Y, Theta = elNode.Theta }); } } return new(true) { Data = elementSatisfies }; } catch (Exception ex) { Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex}"); return new(false, $"Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpGet] [Route("{mapName}/node/{nodeName}")] public async Task> GetNode([FromRoute] string mapName, [FromRoute] string nodeName) { try { var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName); if (map is null) return new(false, $"Không tồn tại map tên = {mapName}"); var node = await MapDb.Nodes.FirstOrDefaultAsync(n => n.MapId == map.Id && n.Name == nodeName); if (node is null) return new(false, $"Không tồn tại node {nodeName} trong map {mapName}"); return new(true) { Data = new NodeDto() { Id = node.Id, Name = node.Name, MapId = node.MapId, X = node.X, Y = node.Y, Theta = node.Theta, AllowedDeviationXy = node.AllowedDeviationXy, AllowedDeviationTheta = node.AllowedDeviationTheta, Actions = node.Actions, } }; } catch (Exception ex) { Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpGet] [Route("{mapName}/element/{elementName}")] public async Task> GetElement([FromRoute] string mapName, [FromRoute] string elementName) { try { var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName); if (map is null) return new(false, $"Không tồn tại map tên = {mapName}"); var el = await MapDb.Elements.FirstOrDefaultAsync(e => e.MapId == map.Id && e.Name == elementName); if (el is null) return new(false, $"Không tồn tại element name = {elementName}"); var elModel = await MapDb.ElementModels.FindAsync(el.ModelId); if (elModel == null) return new(false, $"Không tồn tại element model id = {el.ModelId}"); var elNode = await MapDb.Nodes.FindAsync(el.NodeId); if (elNode is null) return new(false, $"Không tồn tại node id = {el.NodeId}"); return new(true) { Data = new() { Id = el.Id, Name = el.Name, MapId = el.MapId, IsOpen = el.IsOpen, NodeId = el.NodeId, OffsetX = el.OffsetX, OffsetY = el.OffsetY, ModelId = el.ModelId, Content = el.Content, NodeName = elNode.Name, ModelName = elModel.Name, X = elNode.X, Y = elNode.Y, Theta = elNode.Theta } }; } catch (Exception ex) { Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpPatch] [Route("{mapName}/element/{elementName}")] public async Task UpdateElementProperty([FromRoute] string mapName, [FromRoute] string elementName, [FromBody] ElementPropertyUpdateModel model) { try { var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName); if (map is null) return new(false, $"Không tồn tại map tên = {mapName}"); var element = await MapDb.Elements.FirstOrDefaultAsync(m => m.Name == elementName && m.MapId == map.Id); if (element == null) return new(false, $"Không tồn tại element tên = {elementName} trong map tên = {mapName}"); var properties = System.Text.Json.JsonSerializer.Deserialize>(element.Content, JsonOptionExtends.Read); foreach (var property in model.Properties) { var existingProperty = properties?.FirstOrDefault(p => p.Name == property.Name); if (existingProperty != null) { existingProperty.DefaultValue = property.DefaultValue; } else return new(false, $"Không tồn tại property name = {property.Name} trong element"); } var content = System.Text.Json.JsonSerializer.Serialize(properties, JsonOptionExtends.Write); element.Content = content; await MapDb.SaveChangesAsync(); return new(true); } catch (Exception ex) { Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}"); } } [HttpPatch] [Route("{mapName}/element/{elementName}/IsOpen")] public async Task UpdateOpenOfElement([FromRoute] string mapName, [FromRoute] string elementName, [FromQuery] bool isOpen) { try { var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName); if (map is null) return new(false, $"Không tồn tại map tên = {mapName}"); var element = await MapDb.Elements.FirstOrDefaultAsync(m => m.Name == elementName && m.MapId == map.Id); if (element == null) return new(false, $"Không tồn tại element tên = {elementName} trong map tên = {mapName}"); element.IsOpen = isOpen; await MapDb.SaveChangesAsync(); return new(true); } catch (Exception ex) { Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}"); return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}"); } } }