152 lines
4.3 KiB
Go
152 lines
4.3 KiB
Go
package rest
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"net/http"
|
||
"strings"
|
||
|
||
"git.nobla.cn/golang/kos/util/arrays"
|
||
"git.nobla.cn/golang/rest/types"
|
||
)
|
||
|
||
func findCondition(schema *types.Schema, conditions []*types.Condition) *types.Condition {
|
||
for _, cond := range conditions {
|
||
if cond.Column == schema.Column {
|
||
return cond
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func BuildConditions(ctx context.Context, r *http.Request, query *Query, schemas []*types.Schema) (err error) {
|
||
var (
|
||
ok bool
|
||
skip bool
|
||
formValue string
|
||
activeQuery ActiveQuery
|
||
)
|
||
if activeQuery, ok = query.Model().(ActiveQuery); ok {
|
||
if err = activeQuery.BeforeQuery(ctx, query); err != nil {
|
||
return
|
||
}
|
||
}
|
||
if arrays.Exists(r.Method, []string{http.MethodPut, http.MethodPost}) {
|
||
conditions := make([]*types.Condition, 0)
|
||
if err = json.NewDecoder(r.Body).Decode(&conditions); err != nil {
|
||
return
|
||
}
|
||
for _, row := range schemas {
|
||
if row.Native == 0 {
|
||
continue
|
||
}
|
||
cond := findCondition(row, conditions)
|
||
if cond == nil {
|
||
continue
|
||
}
|
||
switch row.Format {
|
||
case types.FormatInteger, types.FormatFloat, types.FormatTimestamp, types.FormatDatetime, types.FormatDate, types.FormatTime:
|
||
switch cond.Expr {
|
||
case types.OperatorBetween:
|
||
if len(cond.Values) == 2 {
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Values[0]).WithExpr(">="))
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Values[1]).WithExpr("<="))
|
||
}
|
||
case types.OperatorGreaterThan:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr(">"))
|
||
case types.OperatorGreaterEqual:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr(">="))
|
||
case types.OperatorLessThan:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr("<"))
|
||
case types.OperatorLessEqual:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr("<="))
|
||
default:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value))
|
||
}
|
||
default:
|
||
switch cond.Expr {
|
||
case types.OperatorLike:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value).WithExpr("LIKE"))
|
||
default:
|
||
query.AndFilterWhere(newCondition(row.Column, cond.Value))
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
qs := r.URL.Query()
|
||
for _, row := range schemas {
|
||
skip = false
|
||
if skip {
|
||
continue
|
||
}
|
||
if row.Native == 0 {
|
||
continue
|
||
}
|
||
//如果是多选的话,直接使用IN操作
|
||
columnName := row.Column + "[]"
|
||
if qs.Has(columnName) && len(qs[columnName]) > 1 {
|
||
query.AndFilterWhere(newConditionWithOperator("IN", row.Column, qs[columnName]))
|
||
continue
|
||
}
|
||
formValue = qs.Get(row.Column)
|
||
switch row.Format {
|
||
case types.FormatString, types.FormatText:
|
||
if row.Attribute.Match == types.MatchExactly {
|
||
query.AndFilterWhere(newCondition(row.Column, formValue))
|
||
} else {
|
||
query.AndFilterWhere(newCondition(row.Column, formValue).WithExpr("LIKE"))
|
||
}
|
||
case types.FormatTime, types.FormatDate, types.FormatDatetime, types.FormatTimestamp:
|
||
var sep string
|
||
seps := []byte{',', '/'}
|
||
for _, s := range seps {
|
||
if strings.IndexByte(formValue, s) > -1 {
|
||
sep = string(s)
|
||
}
|
||
}
|
||
if ss := strings.Split(formValue, sep); len(ss) == 2 {
|
||
query.AndFilterWhere(
|
||
newCondition(row.Column, strings.TrimSpace(ss[0])).WithExpr(">="),
|
||
newCondition(row.Column, strings.TrimSpace(ss[1])).WithExpr("<="),
|
||
)
|
||
} else {
|
||
query.AndFilterWhere(newCondition(row.Column, formValue))
|
||
}
|
||
case types.FormatInteger, types.FormatFloat:
|
||
query.AndFilterWhere(newCondition(row.Column, formValue))
|
||
default:
|
||
if row.Type == types.TypeString {
|
||
if row.Attribute.Match == types.MatchExactly {
|
||
query.AndFilterWhere(newCondition(row.Column, formValue))
|
||
} else {
|
||
query.AndFilterWhere(newCondition(row.Column, formValue).WithExpr("LIKE"))
|
||
}
|
||
} else {
|
||
query.AndFilterWhere(newCondition(row.Column, formValue))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
sortPar := r.FormValue("sort")
|
||
if sortPar != "" {
|
||
sorts := strings.Split(sortPar, ",")
|
||
for _, s := range sorts {
|
||
if s[0] == '-' {
|
||
query.OrderBy(s[1:], "DESC")
|
||
} else {
|
||
if s[0] == '+' {
|
||
query.OrderBy(s[1:], "ASC")
|
||
} else {
|
||
query.OrderBy(s, "ASC")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if activeQuery, ok = query.Model().(ActiveQuery); ok {
|
||
if err = activeQuery.AfterQuery(ctx, query); err != nil {
|
||
return
|
||
}
|
||
}
|
||
return
|
||
}
|