feat(finance): 资金出款支持按具体日期时间(时分秒)筛选

This commit is contained in:
yml2213
2026-09-07 13:46:48 +08:00
parent 3f86dd85ad
commit 5f0b43fe42
5 changed files with 323 additions and 25 deletions
@@ -2,6 +2,7 @@ package adminfinance
import (
"errors"
"fmt"
"net/http"
"strconv"
"strings"
@@ -292,6 +293,45 @@ func parseOperatingExpenseQuery(c *gin.Context) (OperatingExpenseQuery, bool) {
return query, true
}
func parseFlexibleDateTime(raw string, loc *time.Location, isEnd bool) (time.Time, error) {
raw = strings.TrimSpace(raw)
if raw == "" {
return time.Time{}, errors.New("empty time string")
}
formats := []string{
"2006-01-02 15:04:05",
"2006-01-02 15:04",
"2006-01-02T15:04:05",
"2006-01-02T15:04",
time.RFC3339,
"2006-01-02",
}
for _, fmtStr := range formats {
if t, err := time.ParseInLocation(fmtStr, raw, loc); err == nil {
switch fmtStr {
case "2006-01-02":
if isEnd {
return t.AddDate(0, 0, 1).Add(-time.Nanosecond), nil
}
return t, nil
case "2006-01-02 15:04", "2006-01-02T15:04":
if isEnd {
return t.Add(time.Minute).Add(-time.Nanosecond), nil
}
return t, nil
case "2006-01-02 15:04:05", "2006-01-02T15:04:05":
if isEnd {
return t.Add(time.Second - time.Nanosecond), nil
}
return t, nil
default:
return t, nil
}
}
}
return time.Time{}, fmt.Errorf("invalid time format: %s", raw)
}
func parseDateRange(c *gin.Context, defaultLookbackDays int) (time.Time, time.Time, bool) {
loc := timeutil.ShanghaiLocation()
today := timeutil.ShanghaiNow()
@@ -300,24 +340,49 @@ func parseDateRange(c *gin.Context, defaultLookbackDays int) (time.Time, time.Ti
start := defaultStart
end := defaultEnd
if raw := c.Query("start_date"); raw != "" {
parsed, err := time.ParseInLocation("2006-01-02", raw, loc)
rawStart := strings.TrimSpace(c.Query("start_time"))
usingStartTime := rawStart != ""
if rawStart == "" {
rawStart = strings.TrimSpace(c.Query("start_date"))
}
if rawStart != "" {
parsed, err := parseFlexibleDateTime(rawStart, loc, false)
if err != nil {
response.BadRequest(c, "开始日期不正确")
if usingStartTime {
response.BadRequest(c, "开始时间不正确")
} else {
response.BadRequest(c, "开始日期不正确")
}
return start, end, false
}
start = parsed
}
if raw := c.Query("end_date"); raw != "" {
parsed, err := time.ParseInLocation("2006-01-02", raw, loc)
rawEnd := strings.TrimSpace(c.Query("end_time"))
usingEndTime := rawEnd != ""
if rawEnd == "" {
rawEnd = strings.TrimSpace(c.Query("end_date"))
}
if rawEnd != "" {
parsed, err := parseFlexibleDateTime(rawEnd, loc, true)
if err != nil {
response.BadRequest(c, "结束日期不正确")
if usingEndTime {
response.BadRequest(c, "结束时间不正确")
} else {
response.BadRequest(c, "结束日期不正确")
}
return start, end, false
}
end = parsed.AddDate(0, 0, 1).Add(-time.Nanosecond)
end = parsed
}
if start.After(end) {
response.BadRequest(c, "开始日期不能晚于结束日期")
if usingStartTime || usingEndTime {
response.BadRequest(c, "开始时间不能晚于结束时间")
} else {
response.BadRequest(c, "开始日期不能晚于结束日期")
}
return start, end, false
}
return start, end, true