RobotNet/RobotNet.MapManager/Controllers/MapExportController.cs
2025-10-15 15:15:53 +07:00

250 lines
10 KiB
C#

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.Shares;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace RobotNet.MapManager.Controllers;
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class MapExportController(MapEditorDbContext MapDb, MapEditorStorageRepository StorageRepo, IHttpClientFactory HttpClientFactory, LoggerController<MapExportController> Logger) : ControllerBase
{
private readonly byte[] Key = Encoding.UTF8.GetBytes("2512199802031998");
private readonly byte[] IV = Encoding.UTF8.GetBytes("2512199802031998");
[HttpGet]
[Route("encrypt/{Id}")]
public async Task<IActionResult> EncryptMap(Guid Id)
{
try
{
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == Id);
if (map is null) return NotFound($"Map {Id} không tồn tại");
var (usingLocal, url) = StorageRepo.GetUrl("MapImages", $"{Id}");
byte[] imageData = await GetImageDataAsync(usingLocal, url);
var elementModels = MapDb.ElementModels.Where(n => n.MapId == Id);
List<ElementModelExportDto> ElementModelExport = [];
foreach (var elementModel in elementModels)
{
var getImageOpen = StorageRepo.GetUrl("ElementOpenModels", elementModel.Id.ToString());
byte[] imageElementModelOpenData = await GetImageDataAsync(getImageOpen.usingLocal, getImageOpen.url);
var getImageClose = StorageRepo.GetUrl("ElementCloseModels", elementModel.Id.ToString());
byte[] imageElementModelCloseData = await GetImageDataAsync(getImageClose.usingLocal, getImageClose.url);
ElementModelExport.Add(new ElementModelExportDto()
{
Id = elementModel.Id,
Height = elementModel.Height,
Width = elementModel.Width,
Image1Height = elementModel.Image1Height,
Image2Height = elementModel.Image2Height,
Image1Width = elementModel.Image1Width,
Image2Width = elementModel.Image2Width,
Name = elementModel.Name,
Content = elementModel.Content,
ImageOpenData = imageElementModelOpenData,
ImageCloseData = imageElementModelCloseData,
});
}
var nodes = MapDb.Nodes.Where(n => n.MapId == Id);
var edges = MapDb.Edges.Where(n => n.MapId == Id);
var zones = MapDb.Zones.Where(n => n.MapId == Id);
var actions = MapDb.Actions.Where(n => n.MapId == Id);
var elements = MapDb.Elements.Where(n => n.MapId == Id);
var mapDto = new MapExportDto()
{
Id = Id,
Name = map.Name,
Description = map.Description,
Info = new()
{
OriginX = map.OriginX,
OriginY = map.OriginY,
Resolution = map.Resolution,
ViewX = map.ViewX,
ViewY = map.ViewY,
ViewWidth = map.ViewWidth,
ViewHeight = map.ViewHeight,
VDA5050 = map.VDA5050,
},
Setting = new()
{
NodeNameAutoGenerate = map.NodeNameAutoGenerate,
NodeNameTemplate = map.NodeNameTemplateDefault,
NodeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
NodeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
EdgeStraightMaxSpeed = map.EdgeStraightMaxSpeedDefault,
EdgeCurveMaxSpeed = map.EdgeCurveMaxSpeedDefault,
EdgeMaxRotationSpeed = map.EdgeMaxRotationSpeedDefault,
EdgeMinLength = map.EdgeMinLengthDefault,
EdgeMaxHeight = map.EdgeMaxHeightDefault,
EdgeMinHeight = map.EdgeMinHeightDefault,
EdgeRotationAllowed = map.EdgeRotationAllowedDefault,
EdgeDirectionAllowed = map.EdgeDirectionAllowedDefault,
EdgeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
EdgeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
ZoneMinSquare = map.ZoneMinSquareDefault,
},
Data = new()
{
NodeCount = map.NodeCount,
Nodes = [.. nodes.Select(n => new NodeDto()
{
Id = n.Id,
Name = n.Name,
X = n.X,
Y = n.Y,
Theta = n.Theta,
AllowedDeviationXy = n.AllowedDeviationXy,
AllowedDeviationTheta = n.AllowedDeviationTheta,
Actions = n.Actions,
})],
Edges = [.. edges.Select(e => new EdgeDto()
{
ControlPoint1X = e.ControlPoint1X,
ControlPoint1Y = e.ControlPoint1Y,
ControlPoint2X = e.ControlPoint2X,
ControlPoint2Y = e.ControlPoint2Y,
TrajectoryDegree = e.TrajectoryDegree,
EndNodeId = e.EndNodeId,
StartNodeId = e.StartNodeId,
DirectionAllowed = e.DirectionAllowed,
RotationAllowed = e.RotationAllowed,
AllowedDeviationTheta = e.AllowedDeviationTheta,
AllowedDeviationXy = e.AllowedDeviationXy,
MaxHeight = e.MaxHeight,
MinHeight = e.MinHeight,
MaxSpeed = e.MaxSpeed,
MaxRotationSpeed = e.MaxRotationSpeed,
Actions = e.Actions,
})],
Zones = [.. zones.Select(z => new ZoneDto()
{
Type = z.Type,
X1 = z.X1,
Y1 = z.Y1,
X2 = z.X2,
Y2 = z.Y2,
X3 = z.X3,
Y3 = z.Y3,
X4 = z.X4,
Y4 = z.Y4,
})],
Actions = [.. actions.Select(a => new ActionDto()
{
Id = a.Id,
Name = a.Name,
Content = a.Content,
})],
ElementModels = [.. ElementModelExport],
Elements = [.. elements.Select(e => new ElementDto()
{
Name = e.Name,
IsOpen = e.IsOpen,
ModelId = e.ModelId,
NodeId = e.NodeId,
OffsetX = e.OffsetX,
OffsetY = e.OffsetY,
Content = e.Content,
})],
ImageData = imageData,
}
};
var jsonData = JsonSerializer.Serialize(mapDto, JsonOptionExtends.Write);
var data = EncryptDataAES(jsonData, Key, IV);
return File(data, "application/octet-stream", $"{map.Name}.map");
}
catch (Exception ex)
{
Logger.Warning($"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
return NotFound("Hệ thống có lỗi xảy ra");
}
}
[HttpPost]
[Route("decrypt")]
public async Task<MessageResult<MapExportDto>> DecryptMap([FromForm(Name = "importmap")] IFormFile file)
{
try
{
if (file == null || file.Length == 0) return new(false, "File không hợp lệ");
if (!file.FileName.EndsWith(".map", StringComparison.OrdinalIgnoreCase)) return new(false, "Định dạng file không hợp lệ, yêu cầu file .map");
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
byte[] fileBytes = memoryStream.ToArray();
var jsonData = DecryptDataAES(fileBytes, Key, IV);
var mapData = JsonSerializer.Deserialize<MapExportDto>(jsonData, JsonOptionExtends.Read);
if (mapData is null) return new(false, "Dữ liệu không hợp lệ");
else return new(true) { Data = mapData };
}
catch (Exception ex)
{
Logger.Warning($"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
return new(false, $"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
}
}
private static byte[] EncryptDataAES(string data, byte[] key, byte[] iv)
{
using Aes aesAlg = Aes.Create();
aesAlg.Key = key;
aesAlg.IV = iv;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using MemoryStream msEncrypt = new();
using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write);
using (StreamWriter swEncrypt = new(csEncrypt))
{
swEncrypt.Write(data);
}
return msEncrypt.ToArray();
}
private static string DecryptDataAES(byte[] data, byte[] key, byte[] iv)
{
using Aes aesAlg = Aes.Create();
aesAlg.Key = key;
aesAlg.IV = iv;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using MemoryStream msDecrypt = new(data);
using CryptoStream csDecrypt = new(msDecrypt, decryptor, CryptoStreamMode.Read);
using StreamReader srDecrypt = new(csDecrypt);
return srDecrypt.ReadToEnd();
}
public async Task<byte[]> GetImageDataAsync(bool usingLocal, string url)
{
if (!usingLocal)
{
var http = HttpClientFactory.CreateClient();
var response = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
if (!response.IsSuccessStatusCode) return [];
return await response.Content.ReadAsByteArrayAsync();
}
else
{
if (System.IO.File.Exists(url)) return System.IO.File.ReadAllBytes(url);
return [];
}
}
}