LabelReportDateRangeHelper.cs
3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using Volo.Abp;
namespace FoodLabeling.Application.Helpers;
/// <summary>
/// Label Report 统计区间解析(App 7d / 30d / 90d / 自定义)。
/// </summary>
public static class LabelReportDateRangeHelper
{
/// <summary>趋势按日汇总允许的最大天数</summary>
public const int MaxRangeDays = 366;
/// <summary>
/// 解析查询区间。结束日包含当天(闭区间),内部以次日 0 点为区间上界(不含)。
/// </summary>
public static LabelReportResolvedRange Resolve(string? period, DateTime? startDate, DateTime? endDate)
{
var normalized = NormalizePeriod(period);
var endDay = (endDate ?? DateTime.Today).Date;
var endExcl = endDay.AddDays(1);
DateTime startDay;
switch (normalized)
{
case "7d":
startDay = endDay.AddDays(-6);
break;
case "30d":
startDay = endDay.AddDays(-29);
break;
case "90d":
startDay = endDay.AddDays(-89);
break;
case "custom":
if (!startDate.HasValue || !endDate.HasValue)
{
throw new UserFriendlyException("自定义日期须同时传入 startDate 与 endDate");
}
startDay = startDate.Value.Date;
endDay = endDate.Value.Date;
endExcl = endDay.AddDays(1);
if (startDay > endDay)
{
throw new UserFriendlyException("开始日期不能晚于结束日期");
}
break;
default:
startDay = (startDate ?? endDay.AddDays(-6)).Date;
normalized = startDate.HasValue || endDate.HasValue ? "custom" : "7d";
break;
}
if (startDay >= endExcl)
{
startDay = endExcl.AddDays(-1);
}
var dayCount = Math.Max(1, (int)Math.Ceiling((endExcl - startDay).TotalDays));
if (dayCount > MaxRangeDays)
{
throw new UserFriendlyException($"统计区间不能超过 {MaxRangeDays} 天");
}
return new LabelReportResolvedRange
{
Period = normalized,
RangeStart = startDay,
RangeEndExcl = endExcl,
RangeEndInclusive = endDay,
DayCount = dayCount
};
}
private static string NormalizePeriod(string? period)
{
var p = (period ?? "7d").Trim().ToLowerInvariant();
return p switch
{
"7" or "7d" or "last7days" or "last_7_days" => "7d",
"30" or "30d" or "last30days" or "last_30_days" => "30d",
"90" or "90d" or "last90days" or "last_90_days" => "90d",
"custom" => "custom",
_ => p
};
}
}
/// <summary>
/// Label Report 已解析的日期区间。
/// </summary>
public sealed class LabelReportResolvedRange
{
public string Period { get; init; } = "7d";
public DateTime RangeStart { get; init; }
public DateTime RangeEndExcl { get; init; }
public DateTime RangeEndInclusive { get; init; }
public int DayCount { get; init; }
}