feat(store): 扩展临时时段配置

This commit is contained in:
2026-01-20 18:41:34 +08:00
parent 3385674490
commit 32f5bbbd43
15 changed files with 7871 additions and 33 deletions

View File

@@ -39,15 +39,17 @@ public sealed class StoreSchedulerService(
var holidays = await context.StoreHolidays
.AsNoTracking()
.Where(holiday => storeIds.Contains(holiday.StoreId)
&& holiday.IsClosed
&& holiday.Date.Date == today)
&& holiday.Date <= today
&& (holiday.EndDate == null || holiday.EndDate >= today))
.ToListAsync(cancellationToken);
// 3. (空行后) 构造查找表
var hoursLookup = hours
.GroupBy(hour => hour.StoreId)
.ToDictionary(group => group.Key, group => (IReadOnlyList<StoreBusinessHour>)group.ToList());
var holidaySet = holidays.Select(holiday => holiday.StoreId).ToHashSet();
var holidayLookup = holidays
.GroupBy(holiday => holiday.StoreId)
.ToDictionary(group => group.Key, group => (IReadOnlyList<StoreHoliday>)group.ToList());
// 4. (空行后) 判定状态并更新
var updated = 0;
@@ -66,9 +68,33 @@ public sealed class StoreSchedulerService(
}
// 4.3 (空行后) 计算营业状态
var isHolidayClosed = holidaySet.Contains(store.Id);
var storeHolidays = holidayLookup.TryGetValue(store.Id, out var matched) ? matched : [];
var nowTime = now.TimeOfDay;
var isHolidayClosed = storeHolidays.Any(holiday =>
holiday.OverrideType == OverrideType.Closed && IsWithinHolidayTime(holiday, nowTime));
var hasModifiedHours = storeHolidays.Any(holiday => holiday.OverrideType == OverrideType.ModifiedHours);
var isModifiedOpen = hasModifiedHours && storeHolidays.Any(holiday =>
holiday.OverrideType == OverrideType.ModifiedHours && IsWithinHolidayTime(holiday, nowTime));
var isTemporaryOpen = storeHolidays.Any(holiday =>
holiday.OverrideType == OverrideType.TemporaryOpen && IsWithinHolidayTime(holiday, nowTime));
var hasHours = hoursLookup.TryGetValue(store.Id, out var storeHours) && storeHours.Count > 0;
var isOpen = !isHolidayClosed && hasHours && IsWithinBusinessHours(storeHours ?? [], now);
var isOpen = false;
if (isHolidayClosed)
{
isOpen = false;
}
else if (hasModifiedHours)
{
isOpen = isModifiedOpen;
}
else
{
isOpen = hasHours && IsWithinBusinessHours(storeHours ?? [], now);
if (!isOpen && isTemporaryOpen)
{
isOpen = true;
}
}
if (isOpen)
{
if (store.BusinessStatus != StoreBusinessStatus.Open)
@@ -191,6 +217,21 @@ public sealed class StoreSchedulerService(
return false;
}
private static bool IsWithinHolidayTime(StoreHoliday holiday, TimeSpan time)
{
if (holiday.IsAllDay)
{
return true;
}
if (!holiday.StartTime.HasValue || !holiday.EndTime.HasValue)
{
return false;
}
return time >= holiday.StartTime.Value && time < holiday.EndTime.Value;
}
private static DayOfWeek NextDay(DayOfWeek day)
{
var next = (int)day + 1;