优化排班功能

This commit is contained in:
hero920103 committed 2026-11-05 18:00:50 +08:00
1 parent 8acbe732ff
commit 8ba15d87b3
13 files changed
+2463 -565

No files matched your search

+54
View File
@@ -231,6 +231,60 @@ func scDateSpan(start, end string) ([]string, string) {
return dates, ""
}
// scPlanNoEndDate 无期限方案的结束日期哨兵:数据库日期列不支持空串,
// 统一存 2099-12-31,前端按 no_end 标记展示为「无期限」。
const scPlanNoEndDate = "2099-12-31"
// scDateSpanUnbounded 展开任意长度的日期区间,供无期限方案的
// 「当年窗口」使用,不受 scDateSpan 的 92 天上限约束。
func scDateSpanUnbounded(start, end string) ([]string, string) {
startDate, ok := scParseDate(start)
if !ok {
return nil, "开始日期格式错误"
}
endDate, ok := scParseDate(end)
if !ok {
return nil, "结束日期格式错误"
}
if endDate.Before(startDate) {
return nil, "结束日期不能早于开始日期"
}
total := int(endDate.Sub(startDate).Hours()/24) + 1
dates := make([]string, 0, total)
for cursor := startDate; !cursor.After(endDate); cursor = cursor.AddDate(0, 0, 1) {
dates = append(dates, cursor.Format("2006-01-02"))
}
return dates, ""
}
// scIsNoEnd 判断结束日期是否表示无期限(空串或哨兵值)。
func scIsNoEnd(end string) bool {
return end == "" || end >= scPlanNoEndDate
}
// scPlanGenWindow 计算一次预览 / 发布实际展开的日期窗口。
// 普通方案:[start, end] 原样展开;无期限方案:从 max(start, 今天) 生成到
// 当年 12 月 31 日,跨年不自动延续,新的一年需要重新排班。
func scPlanGenWindow(startText, endText string) ([]string, string) {
if !scIsNoEnd(endText) {
return scDateSpan(startText, endText)
}
startDate, ok := scParseDate(startText)
if !ok {
return nil, "开始日期格式错误"
}
windowStart := startDate
today := time.Now()
if today.After(startDate) {
windowStart = today
}
windowEnd := time.Date(today.Year(), 12, 31, 0, 0, 0, 0, today.Location())
if windowEnd.Before(windowStart) {
windowEnd = windowStart
}
return scDateSpanUnbounded(windowStart.Format("2006-01-02"), windowEnd.Format("2006-01-02"))
}
// scMinutes 把 "HH:mm" 转为当日分钟数。
func scMinutes(value string) (int, bool) {
if value == "" {