fix: синхронизации аудиторий

This commit is contained in:
2026-05-11 23:59:13 +03:00
parent 6824d7ce7d
commit 34334e9a8d
6 changed files with 255 additions and 41 deletions
@@ -1,4 +1,5 @@
using UniVerse.Application.DTOs.Sync;
using System.Text.Json.Serialization;
namespace UniVerse.Application.Interfaces;
@@ -20,6 +21,18 @@ public interface IModeusApiClient
// Modeus API response models
public record ModeusEvent(string Id, string Name, DateTime StartsAt, DateTime EndsAt, string? RoomId, string? TeacherId, string? TypeId);
public record ModeusEventsResponse(List<ModeusEvent> Events);
public record ModeusRoom(string Id, string Name, string? Building);
public record ModeusRoomsResponse(List<ModeusRoom> Rooms);
public record ModeusBuilding(string? Id, string? Name, string? NameShort, string? Address);
public record ModeusRoom(string Id, string Name, string? NameShort, ModeusBuilding? Building, int? TotalCapacity, int? WorkingCapacity);
public record ModeusRoomsEmbedded(List<ModeusRoom>? Rooms);
public record ModeusPage(int Size, int TotalElements, int TotalPages, int Number);
public class ModeusRoomsResponse
{
[JsonPropertyName("_embedded")]
public ModeusRoomsEmbedded? Embedded { get; init; }
public ModeusPage? Page { get; init; }
public List<ModeusRoom>? Rooms { get; init; }
[JsonIgnore]
public IReadOnlyList<ModeusRoom> RoomItems => Embedded?.Rooms ?? Rooms ?? [];
}
public record ModeusEmployee(string? Id, string FullName, string? Department);
@@ -29,9 +29,34 @@ public class ModeusApiClient : IModeusApiClient
public async Task<ModeusRoomsResponse> SearchRoomsAsync()
{
var response = await _http.PostAsJsonAsync("/api/proxy/rooms/search", new { });
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ModeusRoomsResponse>() ?? new(new());
const int pageSize = 100;
var allRooms = new List<ModeusRoom>();
var page = 0;
var totalPages = 1;
do
{
var body = new
{
name = "",
sort = "+building.name,+name",
size = pageSize,
page,
deleted = false
};
var response = await _http.PostAsJsonAsync("/api/proxy/rooms/search", body);
response.EnsureSuccessStatusCode();
var payload = await response.Content.ReadFromJsonAsync<ModeusRoomsResponse>() ?? new ModeusRoomsResponse();
allRooms.AddRange(payload.RoomItems);
totalPages = payload.Page?.TotalPages ?? page + 1;
page++;
}
while (page < totalPages);
return new ModeusRoomsResponse { Rooms = allRooms };
}
public async Task<List<ModeusEmployee>> SearchEmployeeAsync(string fullname)
@@ -53,16 +53,53 @@ public class ScheduleSyncService : IScheduleSyncService
public async Task<SyncResultDto> SyncRoomsAsync()
{
int created = 0, updated = 0;
var rooms = await _modeus.SearchRoomsAsync();
foreach (var room in rooms.Rooms)
int created = 0, updated = 0, skipped = 0;
try
{
var existing = await _db.Locations.FirstOrDefaultAsync(l => l.ExternalId == room.Id);
if (existing != null) { existing.Name = room.Name; existing.Building = room.Building; updated++; }
else { _db.Locations.Add(new Location { Name = room.Name, Building = room.Building, ExternalId = room.Id }); created++; }
var rooms = await _modeus.SearchRoomsAsync();
foreach (var room in rooms?.RoomItems ?? [])
{
if (room is null || string.IsNullOrWhiteSpace(room.Id) || string.IsNullOrWhiteSpace(room.Name))
{
skipped++;
continue;
}
var existing = await _db.Locations.FirstOrDefaultAsync(l => l.ExternalId == room.Id);
if (existing != null)
{
existing.Name = room.Name;
existing.Room = room.NameShort;
existing.Building = room.Building?.Name ?? room.Building?.NameShort;
existing.Address = room.Building?.Address;
updated++;
}
else
{
_db.Locations.Add(new Location
{
Name = room.Name,
Room = room.NameShort,
Building = room.Building?.Name ?? room.Building?.NameShort,
Address = room.Building?.Address,
ExternalId = room.Id
});
created++;
}
}
await _db.SaveChangesAsync();
var result = new SyncResultDto(created, updated, skipped, null);
_lastStatus = new SyncStatusDto(DateTime.UtcNow, "completed", result);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Rooms sync failed");
var result = new SyncResultDto(created, updated, skipped, ex.Message);
_lastStatus = new SyncStatusDto(DateTime.UtcNow, "failed", result);
return result;
}
await _db.SaveChangesAsync();
return new SyncResultDto(created, updated, 0, null);
}
public async Task<List<EmployeeDto>> SearchEmployeesAsync(string fullname)