fix(api): 验证时间范围不超过1年以防止查询跨度过大
- 添加 validateTimeRange 函数,实现时间范围格式校验和跨度限制 - 支持字符串和浮点数类型的时间输入转换 - 校验时间格式是否为 YYYY-MM-DD HH:mm:ss,确保格式正确 - 确保结束时间晚于开始时间,避免逻辑错误 - 限制时间跨度最大不能超过365天,防止过大数据范围查询 - 在 create 方法中调用验证逻辑,处理相应的错误返回并终止请求处理
This commit is contained in:
parent
008a5f6328
commit
c56c738992
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue