Initial commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet10.MapEditor.Shared.DTOs.Requests;
|
||||
using RobotNet10.MapManager.Data;
|
||||
|
||||
namespace RobotNet10.MapManager.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Service implementation for managing stations
|
||||
/// </summary>
|
||||
public class StationService(MapDbContext context) : IStationService
|
||||
{
|
||||
private readonly MapDbContext _context = context;
|
||||
|
||||
public async Task<Station> CreateAsync(CreateStationRequest request)
|
||||
{
|
||||
// Check if station ID already exists in this level
|
||||
var exists = await _context.Stations
|
||||
.AnyAsync(s => s.LevelId == request.LayoutLevelId && s.StationId == request.StationId);
|
||||
|
||||
if (exists)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Station with ID '{request.StationId}' already exists in this layout level");
|
||||
}
|
||||
|
||||
using var transaction = await _context.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var station = new Station
|
||||
{
|
||||
LevelId = request.LayoutLevelId,
|
||||
StationId = request.StationId,
|
||||
StationName = request.StationName,
|
||||
StationDescription = request.StationDescription,
|
||||
StationHeight = request.StationHeight,
|
||||
X = request.X,
|
||||
Y = request.Y,
|
||||
Theta = request.Theta
|
||||
};
|
||||
|
||||
_context.Stations.Add(station);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Add interaction nodes if provided
|
||||
if (request.InteractionNodeIds != null && request.InteractionNodeIds.Count != 0)
|
||||
{
|
||||
foreach (var nodeId in request.InteractionNodeIds)
|
||||
{
|
||||
var interactionNode = new StationInteractionNode
|
||||
{
|
||||
StationId = station.Id,
|
||||
NodeId = nodeId
|
||||
};
|
||||
_context.StationInteractionNodes.Add(interactionNode);
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
await transaction.CommitAsync();
|
||||
|
||||
// Reload with interaction nodes
|
||||
return (await GetByIdAsync(station.Id, includeInteractionNodes: true))!;
|
||||
}
|
||||
catch
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Station>> GetStationsByLevelAsync(Guid layoutLevelId, bool includeInteractionNodes = true)
|
||||
{
|
||||
var query = _context.Stations.Where(s => s.LevelId == layoutLevelId);
|
||||
|
||||
if (includeInteractionNodes)
|
||||
{
|
||||
query = query
|
||||
.Include(s => s.InteractionNodes)
|
||||
.ThenInclude(sin => sin.Node);
|
||||
}
|
||||
|
||||
return await query.OrderBy(s => s.StationId).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Station?> GetByIdAsync(Guid stationId, bool includeInteractionNodes = true)
|
||||
{
|
||||
var query = _context.Stations.Where(s => s.Id == stationId);
|
||||
|
||||
if (includeInteractionNodes)
|
||||
{
|
||||
query = query
|
||||
.Include(s => s.InteractionNodes)
|
||||
.ThenInclude(sin => sin.Node)
|
||||
.ThenInclude(n => n.VehicleProperties);
|
||||
}
|
||||
|
||||
return await query.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<Station> UpdateAsync(Guid stationId, UpdateStationRequest request)
|
||||
{
|
||||
var station = await GetByIdAsync(stationId, includeInteractionNodes: true) ??
|
||||
throw new InvalidOperationException($"Station with ID '{stationId}' not found");
|
||||
|
||||
// Update properties
|
||||
if (request.StationName != null)
|
||||
station.StationName = request.StationName;
|
||||
|
||||
if (request.StationDescription != null)
|
||||
station.StationDescription = request.StationDescription;
|
||||
|
||||
if (request.StationHeight.HasValue)
|
||||
station.StationHeight = request.StationHeight.Value;
|
||||
|
||||
if (request.X.HasValue)
|
||||
station.X = request.X.Value;
|
||||
|
||||
if (request.Y.HasValue)
|
||||
station.Y = request.Y.Value;
|
||||
|
||||
if (request.Theta.HasValue)
|
||||
station.Theta = request.Theta.Value;
|
||||
|
||||
// Update interaction nodes if provided
|
||||
if (request.InteractionNodeIds != null)
|
||||
{
|
||||
// Remove existing interaction nodes
|
||||
var existingInteractionNodes = await _context.StationInteractionNodes
|
||||
.Where(sin => sin.StationId == stationId)
|
||||
.ToListAsync();
|
||||
_context.StationInteractionNodes.RemoveRange(existingInteractionNodes);
|
||||
|
||||
// Add new interaction nodes
|
||||
foreach (var nodeId in request.InteractionNodeIds)
|
||||
{
|
||||
// Verify node exists
|
||||
var nodeExists = await _context.Nodes.AnyAsync(n => n.Id == nodeId);
|
||||
if (!nodeExists)
|
||||
{
|
||||
throw new InvalidOperationException($"Node with ID '{nodeId}' not found");
|
||||
}
|
||||
|
||||
var interactionNode = new StationInteractionNode
|
||||
{
|
||||
StationId = stationId,
|
||||
NodeId = nodeId
|
||||
};
|
||||
_context.StationInteractionNodes.Add(interactionNode);
|
||||
}
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Reload with interaction nodes
|
||||
return (await GetByIdAsync(stationId, includeInteractionNodes: true))!;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(Guid stationId)
|
||||
{
|
||||
var station = await GetByIdAsync(stationId, includeInteractionNodes: false);
|
||||
if (station == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete interaction nodes (cascade will handle this, but explicit for clarity)
|
||||
var interactionNodes = await _context.StationInteractionNodes
|
||||
.Where(sin => sin.StationId == stationId)
|
||||
.ToListAsync();
|
||||
_context.StationInteractionNodes.RemoveRange(interactionNodes);
|
||||
|
||||
// Delete station
|
||||
_context.Stations.Remove(station);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user