Browse Source

feat: Add calendar module

pull/1482/head
colin 4 months ago
parent
commit
f99cf57501
  1. 3
      aspnet-core/LINGYUN.MicroService.Aspire.slnx
  2. 3
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/FodyWeavers.xml
  3. 21
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN.Abp.Calendar.csproj
  4. 9
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/AbpCalendarModule.cs
  5. 40
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/AbpCalendarOptions.cs
  6. 24
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/IWorkdayCalendarService.cs
  7. 18
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/IWorkdayCalendarStore.cs
  8. 19
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/NullWorkdayCalendarStore.cs
  9. 21
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/SpecialDateInfo.cs
  10. 24
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/SpecialDateType.cs
  11. 27
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/WorkTimeRange.cs
  12. 34
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/WorkdayCalendarInfo.cs
  13. 117
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/WorkdayCalendarService.cs
  14. 15
      aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/README.md

3
aspnet-core/LINGYUN.MicroService.Aspire.slnx

@ -90,6 +90,9 @@
<Folder Name="/framework/authorization/">
<Project Path="framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN.Abp.Authorization.OrganizationUnits.csproj" />
</Folder>
<Folder Name="/framework/calendars/">
<Project Path="framework/calendars/LINGYUN.Abp.Calendar/LINGYUN.Abp.Calendar.csproj" Id="2fee90a2-01aa-4417-9529-79bb10b8850c" />
</Folder>
<Folder Name="/framework/cli/">
<Project Path="framework/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj" />
</Folder>

3
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

21
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN.Abp.Calendar.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.WorkdayCalendar</AssemblyName>
<PackageId>LINGYUN.Abp.WorkdayCalendar</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Timing" />
</ItemGroup>
</Project>

9
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/AbpCalendarModule.cs

@ -0,0 +1,9 @@
using Volo.Abp.Modularity;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.Calendar;
[DependsOn(typeof(AbpTimingModule))]
public class AbpCalendarModule : AbpModule
{
}

40
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/AbpCalendarOptions.cs

@ -0,0 +1,40 @@
using System;
namespace LINGYUN.Abp.Calendar;
public class AbpCalendarOptions
{
/// <summary>
/// 默认工作日范围
/// 默认: 周一到周五
/// </summary>
public DayOfWeek[] DefaultWorkdays { get; set; }
/// <summary>
/// 是否启用工作时间限制
/// 默认: true
/// </summary>
public bool EnableWorkTimeRestriction { get; set; }
/// <summary>
/// 默认工作时间范围
/// 默认: 09:00-12:00、13:00-18:00
/// </summary>
public WorkTimeRange[] DefaultWorkTimes { get; set; }
public AbpCalendarOptions()
{
DefaultWorkdays = new[]
{
DayOfWeek.Monday,
DayOfWeek.Tuesday,
DayOfWeek.Wednesday,
DayOfWeek.Thursday,
DayOfWeek.Friday
};
EnableWorkTimeRestriction = true;
DefaultWorkTimes = new[]
{
new WorkTimeRange(new TimeSpan(9, 0, 0), new TimeSpan(12, 0, 0)),
new WorkTimeRange(new TimeSpan(13, 0, 0), new TimeSpan(18, 0, 0)),
};
}
}

24
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/IWorkdayCalendarService.cs

@ -0,0 +1,24 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Calendar;
public interface IWorkdayCalendarService
{
/// <summary>
/// 检查指定时间是否在工作日
/// </summary>
Task<bool> IsWorkdayAsync(DateOnly date);
/// <summary>
/// 检查指定时间是否在工作时间
/// </summary>
/// <param name="dateTime"></param>
/// <returns></returns>
Task<bool> IsInWorkTimeAsync(DateTime dateTime);
/// <summary>
/// 获取下一个工作日
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
Task<DateOnly> GetNextWorkdayAsync(DateOnly date);
}

18
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/IWorkdayCalendarStore.cs

@ -0,0 +1,18 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Calendar;
public interface IWorkdayCalendarStore
{
/// <summary>
/// 获取特殊日期
/// </summary>
/// <param name="date">日期</param>
/// <returns></returns>
Task<SpecialDateInfo?> FindSpecialDateAsync(DateOnly date);
/// <summary>
/// 获取默认工作日历
/// </summary>
Task<WorkdayCalendarInfo?> FindDefaultCalendarAsync();
}

19
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/NullWorkdayCalendarStore.cs

@ -0,0 +1,19 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Calendar;
[Dependency(TryRegister = true)]
public class NullWorkdayCalendarStore : IWorkdayCalendarStore, ISingletonDependency
{
public Task<WorkdayCalendarInfo?> FindDefaultCalendarAsync()
{
return Task.FromResult<WorkdayCalendarInfo?>(null);
}
public Task<SpecialDateInfo?> FindSpecialDateAsync(DateOnly date)
{
return Task.FromResult<SpecialDateInfo?>(null);
}
}

21
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/SpecialDateInfo.cs

@ -0,0 +1,21 @@
using System;
namespace LINGYUN.Abp.Calendar;
/// <summary>
/// 特殊日期
/// </summary>
public class SpecialDateInfo
{
/// <summary>
/// 日期
/// </summary>
public DateOnly Date { get; set; }
/// <summary>
/// 特殊日期类型
/// </summary>
public SpecialDateType Type { get; set; }
/// <summary>
/// 特殊日期描述
/// </summary>
public string? Description { get; set; }
}

24
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/SpecialDateType.cs

@ -0,0 +1,24 @@
using System.ComponentModel;
namespace LINGYUN.Abp.Calendar;
/// <summary>
/// 特殊日期类型
/// </summary>
public enum SpecialDateType
{
/// <summary>
/// 法定节假日
/// </summary>
[Description("法定节假日")]
Holiday = 0,
/// <summary>
/// 特殊工作日
/// </summary>
[Description("特殊工作日")]
SpecialWorkday = 1,
/// <summary>
/// 自定义假期
/// </summary>
[Description("自定义假期")]
CustomHoliday = 2
}

27
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/WorkTimeRange.cs

@ -0,0 +1,27 @@
using System;
namespace LINGYUN.Abp.Calendar;
/// <summary>
/// 工作时间范围
/// </summary>
public class WorkTimeRange
{
/// <summary>
/// 开始时间
/// </summary>
public TimeSpan StartTime { get; set; }
/// <summary>
/// 截止时间
/// </summary>
public TimeSpan EndTime { get; set; }
public WorkTimeRange()
{
}
public WorkTimeRange(TimeSpan startTime, TimeSpan endTime)
{
StartTime = startTime;
EndTime = endTime;
}
}

34
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/WorkdayCalendarInfo.cs

@ -0,0 +1,34 @@
using System;
namespace LINGYUN.Abp.Calendar;
/// <summary>
/// 工作日历信息
/// </summary>
public class WorkdayCalendarInfo
{
/// <summary>
/// 日历名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 默认日历
/// </summary>
public bool IsDefault { get; set; }
/// <summary>
/// 工作日范围
/// </summary>
public DayOfWeek[] Workdays { get; set; }
/// <summary>
/// 工作时间范围
/// </summary>
public WorkTimeRange[]? WorkTimes { get; set; }
/// <summary>
/// 是否启用工作时间限制
/// </summary>
public bool EnableWorkTimeRestriction { get; set; }
/// <summary>
/// 特殊日期列表
/// </summary>
public SpecialDateInfo[]? SpecialDates { get; set; }
}

117
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/LINGYUN/Abp/Calendar/WorkdayCalendarService.cs

@ -0,0 +1,117 @@
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Calendar;
public class WorkdayCalendarService : IWorkdayCalendarService, ITransientDependency
{
private readonly AbpCalendarOptions _options;
private readonly IWorkdayCalendarStore _workdayCalendarStore;
public WorkdayCalendarService(
IOptions<AbpCalendarOptions> options,
IWorkdayCalendarStore workdayCalendarStore)
{
_options = options.Value;
_workdayCalendarStore = workdayCalendarStore;
}
public async virtual Task<DateOnly> GetNextWorkdayAsync(DateOnly date)
{
var nextDay = date.AddDays(1);
// 以31天为限
var maxAttempts = 30;
for (var i = 0; i < maxAttempts; i++)
{
if (await IsWorkdayAsync(nextDay))
{
return nextDay;
}
nextDay = nextDay.AddDays(1);
}
// 如果30天内都找不到工作日,返回原日期+1天
return date.AddDays(1);
}
public async virtual Task<bool> IsWorkdayAsync(DateOnly date)
{
// 特殊工作日定义
var specialDate = await _workdayCalendarStore.FindSpecialDateAsync(date);
if (specialDate != null)
{
return specialDate.Type == SpecialDateType.SpecialWorkday;
}
// 获取默认工作日历定义
var calendar = await _workdayCalendarStore.FindDefaultCalendarAsync();
if (calendar == null)
{
// 未定义默认工作日历, 获取系统定义工作日范围
return _options.DefaultWorkdays.Contains(date.DayOfWeek);
}
// 特殊工作日范围
if (calendar.SpecialDates != null &&
calendar.SpecialDates.Any(x => x.Date == date && x.Type == SpecialDateType.SpecialWorkday))
{
return true;
}
// 工作日范围
if (!calendar.Workdays.Contains(date.DayOfWeek))
{
return false;
}
return false;
}
public async virtual Task<bool> IsInWorkTimeAsync(DateTime time)
{
var nowDate = DateOnly.FromDateTime(time);
// 特殊工作日定义
var specialDate = await _workdayCalendarStore.FindSpecialDateAsync(nowDate);
if (specialDate != null)
{
return specialDate.Type == SpecialDateType.SpecialWorkday;
}
// 获取默认工作日历定义
var calendar = await _workdayCalendarStore.FindDefaultCalendarAsync();
if (calendar == null)
{
// 未定义默认工作日历, 获取系统定义工作日范围
if (!_options.DefaultWorkdays.Contains(nowDate.DayOfWeek))
{
return false;
}
if (_options.EnableWorkTimeRestriction &&
!_options.DefaultWorkTimes.Any(timeRange => timeRange.StartTime >= time.TimeOfDay && timeRange.EndTime <= time.TimeOfDay))
{
return false;
}
return true;
}
// 特殊工作日范围
if (calendar.SpecialDates != null &&
calendar.SpecialDates.Any(x => x.Date == nowDate && x.Type == SpecialDateType.SpecialWorkday))
{
return true;
}
// 工作日范围
if (!calendar.Workdays.Contains(nowDate.DayOfWeek))
{
return false;
}
// 工作时间范围
if (calendar.EnableWorkTimeRestriction &&
calendar.WorkTimes != null)
{
return calendar.WorkTimes.Any(x => x.StartTime >= time.TimeOfDay && x.EndTime <= time.TimeOfDay);
}
return false;
}
}

15
aspnet-core/framework/calendars/LINGYUN.Abp.Calendar/README.md

@ -0,0 +1,15 @@
# LINGYUN.Abp.Calendar
日历模块, 定义系统日历参数, 用于特定场景.
#### 注意
## 功能特性
## 配置使用
## 更多信息
Loading…
Cancel
Save