Yc.Box.Types.TimeSlots
1.2.0
dotnet add package Yc.Box.Types.TimeSlots --version 1.2.0
NuGet\Install-Package Yc.Box.Types.TimeSlots -Version 1.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Yc.Box.Types.TimeSlots" Version="1.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Yc.Box.Types.TimeSlots" Version="1.2.0" />
<PackageReference Include="Yc.Box.Types.TimeSlots" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Yc.Box.Types.TimeSlots --version 1.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Yc.Box.Types.TimeSlots, 1.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Yc.Box.Types.TimeSlots@1.2.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Yc.Box.Types.TimeSlots&version=1.2.0
#tool nuget:?package=Yc.Box.Types.TimeSlots&version=1.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Yc.Box.Types.TimeSlots
Библиотека типов для работы с временными слотами в проектах YC. Предоставляет модель для управления временными интервалами с поддержкой доступности, ограничений участников и метаданных.
🚀 Возможности
- Временные слоты - Модель для представления временных интервалов
- Управление доступностью - Контроль доступности слотов
- Ограничения участников - Максимальное и текущее количество участников
- Автоматические вычисления - Продолжительность слота вычисляется автоматически
- Метаданные - Временные метки создания и обновления
- Типобезопасность - Полная поддержка типизированных моделей
📦 Установка
dotnet add package Yc.Box.Types.TimeSlots
🔧 Использование
Создание временного слота
using Yc.Box.Types.TimeSlots.Models;
public class TimeSlotService
{
public YcTimeSlot CreateTimeSlot(string name, TimeSpan startTime, TimeSpan endTime)
{
return new YcTimeSlot
{
Id = Guid.NewGuid(),
Name = name,
StartTime = startTime,
EndTime = endTime,
Description = "Описание временного слота",
IsAvailable = true,
MaxParticipants = 10,
CurrentParticipants = 0
};
}
public YcTimeSlot CreateMorningSlot()
{
return new YcTimeSlot
{
Id = Guid.NewGuid(),
Name = "Утренний слот",
StartTime = TimeSpan.FromHours(9),
EndTime = TimeSpan.FromHours(12),
Description = "Утренние часы работы",
IsAvailable = true,
MaxParticipants = 5,
CurrentParticipants = 0
};
}
public YcTimeSlot CreateAfternoonSlot()
{
return new YcTimeSlot
{
Id = Guid.NewGuid(),
Name = "Дневной слот",
StartTime = TimeSpan.FromHours(13),
EndTime = TimeSpan.FromHours(17),
Description = "Дневные часы работы",
IsAvailable = true,
MaxParticipants = 8,
CurrentParticipants = 0
};
}
}
Управление доступностью
public class TimeSlotManager
{
public bool IsSlotAvailable(YcTimeSlot timeSlot)
{
return timeSlot.IsAvailable &&
timeSlot.CurrentParticipants < timeSlot.MaxParticipants;
}
public bool CanAddParticipant(YcTimeSlot timeSlot)
{
if (!timeSlot.IsAvailable)
return false;
if (timeSlot.MaxParticipants.HasValue)
return timeSlot.CurrentParticipants < timeSlot.MaxParticipants.Value;
return true; // Нет ограничений
}
public bool AddParticipant(YcTimeSlot timeSlot)
{
if (!CanAddParticipant(timeSlot))
return false;
timeSlot.CurrentParticipants++;
timeSlot.UpdatedAt = DateTime.UtcNow;
return true;
}
public bool RemoveParticipant(YcTimeSlot timeSlot)
{
if (timeSlot.CurrentParticipants > 0)
{
timeSlot.CurrentParticipants--;
timeSlot.UpdatedAt = DateTime.UtcNow;
return true;
}
return false;
}
public void SetAvailability(YcTimeSlot timeSlot, bool isAvailable)
{
timeSlot.IsAvailable = isAvailable;
timeSlot.UpdatedAt = DateTime.UtcNow;
}
}
Работа с продолжительностью
public class TimeSlotCalculator
{
public TimeSpan GetSlotDuration(YcTimeSlot timeSlot)
{
return timeSlot.Duration; // Автоматически вычисляется
}
public bool IsSlotValid(YcTimeSlot timeSlot)
{
return timeSlot.StartTime < timeSlot.EndTime;
}
public bool DoSlotsOverlap(YcTimeSlot slot1, YcTimeSlot slot2)
{
return slot1.StartTime < slot2.EndTime && slot2.StartTime < slot1.EndTime;
}
public TimeSpan GetOverlapDuration(YcTimeSlot slot1, YcTimeSlot slot2)
{
if (!DoSlotsOverlap(slot1, slot2))
return TimeSpan.Zero;
var overlapStart = slot1.StartTime > slot2.StartTime ? slot1.StartTime : slot2.StartTime;
var overlapEnd = slot1.EndTime < slot2.EndTime ? slot1.EndTime : slot2.EndTime;
return overlapEnd - overlapStart;
}
public List<YcTimeSlot> GetAvailableSlots(List<YcTimeSlot> slots)
{
return slots.Where(s => s.IsAvailable && s.CurrentParticipants < s.MaxParticipants).ToList();
}
public List<YcTimeSlot> GetSlotsByDuration(List<YcTimeSlot> slots, TimeSpan minDuration)
{
return slots.Where(s => s.Duration >= minDuration).ToList();
}
}
Интеграция с расписанием
public class ScheduleTimeSlotManager
{
public List<YcTimeSlot> CreateDailySlots(DateTime date, TimeSpan workStart, TimeSpan workEnd, int slotDurationMinutes)
{
var slots = new List<YcTimeSlot>();
var currentTime = workStart;
var slotNumber = 1;
while (currentTime < workEnd)
{
var slotEnd = currentTime.Add(TimeSpan.FromMinutes(slotDurationMinutes));
if (slotEnd > workEnd)
slotEnd = workEnd;
var slot = new YcTimeSlot
{
Id = Guid.NewGuid(),
Name = $"Слот {slotNumber}",
StartTime = currentTime,
EndTime = slotEnd,
Description = $"Временной слот {slotNumber} на {date:dd.MM.yyyy}",
IsAvailable = true,
MaxParticipants = 5,
CurrentParticipants = 0,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
slots.Add(slot);
currentTime = slotEnd;
slotNumber++;
}
return slots;
}
public Dictionary<DayOfWeek, List<YcTimeSlot>> CreateWeeklySchedule(
TimeSpan workStart, TimeSpan workEnd, int slotDurationMinutes)
{
var weeklySchedule = new Dictionary<DayOfWeek, List<YcTimeSlot>>();
for (int day = 0; day < 7; day++)
{
var dayOfWeek = (DayOfWeek)day;
var slots = CreateDailySlots(DateTime.Today, workStart, workEnd, slotDurationMinutes);
weeklySchedule[dayOfWeek] = slots;
}
return weeklySchedule;
}
}
API контроллер с временными слотами
using Yc.Box.Types.TimeSlots.Models;
using Yc.Box.Types.Core.Models.ApiResponses;
[ApiController]
[Route("api/[controller]")]
public class TimeSlotsController : ControllerBase
{
private readonly TimeSlotService _timeSlotService;
private readonly TimeSlotManager _timeSlotManager;
public TimeSlotsController(TimeSlotService timeSlotService, TimeSlotManager timeSlotManager)
{
_timeSlotService = timeSlotService;
_timeSlotManager = timeSlotManager;
}
[HttpGet]
public ActionResult<YcApiResponse<List<YcTimeSlot>>> GetTimeSlots()
{
var slots = _timeSlotService.GetAllSlots();
return this.SuccessResponse(slots, "Временные слоты получены");
}
[HttpGet("available")]
public ActionResult<YcApiResponse<List<YcTimeSlot>>> GetAvailableSlots()
{
var slots = _timeSlotService.GetAllSlots();
var availableSlots = slots.Where(s => _timeSlotManager.IsSlotAvailable(s)).ToList();
return this.SuccessResponse(availableSlots, "Доступные слоты получены");
}
[HttpPost]
public ActionResult<YcApiResponse<YcTimeSlot>> CreateTimeSlot([FromBody] CreateTimeSlotRequest request)
{
if (!ModelState.IsValid)
return this.ValidationError();
var timeSlot = _timeSlotService.CreateTimeSlot(
request.Name,
request.StartTime,
request.EndTime);
return this.SuccessResponse(timeSlot, "Временной слот создан");
}
[HttpPost("{id}/participants")]
public ActionResult<YcApiResponse> AddParticipant(Guid id)
{
var timeSlot = _timeSlotService.GetById(id);
if (timeSlot == null)
return this.NotFoundError($"Временной слот с ID {id} не найден");
if (!_timeSlotManager.AddParticipant(timeSlot))
return this.ValidationError("Не удалось добавить участника. Слот недоступен или заполнен.");
return this.SuccessResponse("Участник добавлен");
}
[HttpDelete("{id}/participants")]
public ActionResult<YcApiResponse> RemoveParticipant(Guid id)
{
var timeSlot = _timeSlotService.GetById(id);
if (timeSlot == null)
return this.NotFoundError($"Временной слот с ID {id} не найден");
if (!_timeSlotManager.RemoveParticipant(timeSlot))
return this.ValidationError("Не удалось удалить участника.");
return this.SuccessResponse("Участник удален");
}
}
📋 Свойства модели YcTimeSlot
Основные свойства
Id
- Уникальный идентификатор слотаName
- Название слотаStartTime
- Время началаEndTime
- Время окончанияDescription
- Описание слота
Управление доступностью
IsAvailable
- Доступен ли слотMaxParticipants
- Максимальное количество участниковCurrentParticipants
- Текущее количество участников
Вычисляемые свойства
Duration
- Продолжительность слота (EndTime - StartTime)
Метаданные
CreatedAt
- Дата созданияUpdatedAt
- Дата обновления
🏗️ Структура пакета
Yc.Box.Types.TimeSlots/
└── Models/
└── YcTimeSlot.cs # Модель временного слота
🔒 Совместимость
- .NET 9.0+
- Все классы имеют префикс
Yc
для избежания конфликтов имен
📄 Лицензия
Проект YC Team
🤝 Поддержка
Для вопросов и предложений обращайтесь к команде разработки YC.
📈 Версии
- 1.0.0 - Первоначальный релиз с моделью временного слота
- 1.1.0 - Добавлены вычисляемые свойства
- 1.2.0 - Переименование классов с префиксом Yc
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.