fix(api): 验证时间范围不超过1年以防止查询跨度过大

- 添加 validateTimeRange 函数,实现时间范围格式校验和跨度限制
- 支持字符串和浮点数类型的时间输入转换
- 校验时间格式是否为 YYYY-MM-DD HH:mm:ss,确保格式正确
- 确保结束时间晚于开始时间,避免逻辑错误
- 限制时间跨度最大不能超过365天,防止过大数据范围查询
- 在 create 方法中调用验证逻辑,处理相应的错误返回并终止请求处理
This commit is contained in:
zhouyonggao 2025-12-22 11:09:37 +08:00
parent 008a5f6328
commit c56c738992
1 changed files with 60 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package api
import ( import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
@ -21,6 +22,55 @@ import (
"time" "time"
) )
// validateTimeRange 验证时间范围不超过1年
func validateTimeRange(startVal, endVal interface{}) error {
var startStr, endStr string
// 转换start时间
switch v := startVal.(type) {
case string:
startStr = v
case float64:
startStr = utils.ToString(v)
default:
return errors.New("开始时间格式无效")
}
// 转换end时间
switch v := endVal.(type) {
case string:
endStr = v
case float64:
endStr = utils.ToString(v)
default:
return errors.New("结束时间格式无效")
}
// 解析时间
layout := "2006-01-02 15:04:05"
startTime, err1 := time.Parse(layout, strings.TrimSpace(startStr))
endTime, err2 := time.Parse(layout, strings.TrimSpace(endStr))
if err1 != nil || err2 != nil {
return errors.New("时间格式错误,应为 YYYY-MM-DD HH:mm:ss")
}
// 检查结束时间是否晚于开始时间
if !endTime.After(startTime) {
return errors.New("结束时间必须晚于开始时间")
}
// 计算时间跨度
duration := endTime.Sub(startTime)
oneYear := 365 * 24 * time.Hour
if duration > oneYear {
return fmt.Errorf("时间跨度超过1年限制当前跨度为 %.1f 天,最多允许 365 天", duration.Hours()/24)
}
return nil
}
type ExportsAPI struct { type ExportsAPI struct {
Meta *sql.DB Meta *sql.DB
Marketing *sql.DB Marketing *sql.DB
@ -142,11 +192,21 @@ func (a *ExportsAPI) create(w http.ResponseWriter, r *http.Request) {
fail(w, r, http.StatusBadRequest, "create_time_between 需要两个时间值") fail(w, r, http.StatusBadRequest, "create_time_between 需要两个时间值")
return return
} }
// 验证时间跨度不超过1年
if err := validateTimeRange(t[0], t[1]); err != nil {
fail(w, r, http.StatusBadRequest, err.Error())
return
}
case []string: case []string:
if len(t) != 2 { if len(t) != 2 {
fail(w, r, http.StatusBadRequest, "create_time_between 需要两个时间值") fail(w, r, http.StatusBadRequest, "create_time_between 需要两个时间值")
return return
} }
// 验证时间跨度不超过1年
if err := validateTimeRange(t[0], t[1]); err != nil {
fail(w, r, http.StatusBadRequest, err.Error())
return
}
default: default:
fail(w, r, http.StatusBadRequest, "create_time_between 格式错误") fail(w, r, http.StatusBadRequest, "create_time_between 格式错误")
return return