|
@@ -10,6 +10,7 @@ import (
|
|
|
"git.nspix.com/golang/rest/v3/inflector"
|
|
|
"gorm.io/gorm"
|
|
|
"gorm.io/gorm/clause"
|
|
|
+ httppkg "net/http"
|
|
|
"path"
|
|
|
"reflect"
|
|
|
"strconv"
|
|
@@ -34,6 +35,16 @@ const (
|
|
|
ErrorAccessDeniedMessage = "access denied"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ OperatorEqual = "eq"
|
|
|
+ OperatorGreaterThan = "gt"
|
|
|
+ OperatorGreaterEqual = "ge"
|
|
|
+ OperatorLessThan = "lt"
|
|
|
+ OperatorLessEqual = "le"
|
|
|
+ OperatorLike = "like"
|
|
|
+ OperatorBetween = "between"
|
|
|
+)
|
|
|
+
|
|
|
type (
|
|
|
DiffAttr struct {
|
|
|
Column string `json:"column"`
|
|
@@ -42,6 +53,13 @@ type (
|
|
|
NewValue interface{} `json:"new_value"`
|
|
|
}
|
|
|
|
|
|
+ Condition struct {
|
|
|
+ Column string `json:"column"`
|
|
|
+ Expr string `json:"expr"`
|
|
|
+ Value interface{} `json:"value,omitempty"`
|
|
|
+ Values []interface{} `json:"values,omitempty"`
|
|
|
+ }
|
|
|
+
|
|
|
Restful struct {
|
|
|
model Model
|
|
|
opts *Options
|
|
@@ -151,6 +169,15 @@ func (r *Restful) hasScenario(s string) bool {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
+func (r *Restful) findCondition(schema *Schema, conditions []*Condition) *Condition {
|
|
|
+ for _, cond := range conditions {
|
|
|
+ if cond.Column == schema.Column {
|
|
|
+ return cond
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func (r *Restful) prepareConditions(ctx context.Context, requestCtx *http.Context, query *Query, schemas []*Schema) (err error) {
|
|
|
var (
|
|
|
ok bool
|
|
@@ -170,50 +197,90 @@ func (r *Restful) prepareConditions(ctx context.Context, requestCtx *http.Contex
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
- //处理默认的搜索
|
|
|
- for _, schema := range schemas {
|
|
|
- skip = false
|
|
|
- if skip {
|
|
|
- continue
|
|
|
- }
|
|
|
- if schema.Native == 0 {
|
|
|
- continue
|
|
|
+ if requestCtx.Request().Method == httppkg.MethodPut || requestCtx.Request().Method == httppkg.MethodPost {
|
|
|
+ conditions := make([]*Condition, 0)
|
|
|
+ if err = requestCtx.Bind(&conditions); err != nil {
|
|
|
+ return
|
|
|
}
|
|
|
- formValue = requestCtx.FormValue(schema.Column)
|
|
|
- switch schema.Format {
|
|
|
- case FormatString, FormatText:
|
|
|
- if schema.Attribute.Match == MatchExactly {
|
|
|
- query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
- } else {
|
|
|
- query.AndFilterWhere(NewCond(schema.Column, formValue).WithExpr("LIKE"))
|
|
|
- }
|
|
|
- case FormatTime, FormatDate, FormatDatetime, FormatTimestamp:
|
|
|
- var sep string
|
|
|
- seps := []byte{',', '/'}
|
|
|
- for _, s := range seps {
|
|
|
- if strings.IndexByte(formValue, s) > -1 {
|
|
|
- sep = string(s)
|
|
|
+ for _, schema := range schemas {
|
|
|
+ cond := r.findCondition(schema, conditions)
|
|
|
+ if cond == nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ switch schema.Format {
|
|
|
+ case FormatInteger, FormatFloat, FormatTimestamp, FormatDatetime, FormatDate, FormatTime:
|
|
|
+ switch cond.Expr {
|
|
|
+ case OperatorBetween:
|
|
|
+ if len(cond.Values) == 2 {
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Values[0]).WithExpr(">="))
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Values[1]).WithExpr("<="))
|
|
|
+ }
|
|
|
+ case OperatorGreaterThan:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value).WithExpr(">"))
|
|
|
+ case OperatorGreaterEqual:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value).WithExpr(">="))
|
|
|
+ case OperatorLessThan:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value).WithExpr("<"))
|
|
|
+ case OperatorLessEqual:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value).WithExpr("<="))
|
|
|
+ default:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value))
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ switch cond.Expr {
|
|
|
+ case OperatorLike:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value).WithExpr("LIKE"))
|
|
|
+ default:
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, cond.Value))
|
|
|
}
|
|
|
}
|
|
|
- if ss := strings.Split(formValue, sep); len(ss) == 2 {
|
|
|
- query.AndFilterWhere(
|
|
|
- NewCond(schema.Column, strings.TrimSpace(ss[0])).WithExpr(">="),
|
|
|
- NewCond(schema.Column, strings.TrimSpace(ss[1])).WithExpr("<="),
|
|
|
- )
|
|
|
- } else {
|
|
|
- query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //处理默认的搜索
|
|
|
+ for _, schema := range schemas {
|
|
|
+ skip = false
|
|
|
+ if skip {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if schema.Native == 0 {
|
|
|
+ continue
|
|
|
}
|
|
|
- case FormatInteger, FormatFloat:
|
|
|
- query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
- default:
|
|
|
- if schema.Type == TypeString {
|
|
|
+ formValue = requestCtx.FormValue(schema.Column)
|
|
|
+ switch schema.Format {
|
|
|
+ case FormatString, FormatText:
|
|
|
if schema.Attribute.Match == MatchExactly {
|
|
|
query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
} else {
|
|
|
query.AndFilterWhere(NewCond(schema.Column, formValue).WithExpr("LIKE"))
|
|
|
}
|
|
|
- } else {
|
|
|
+ case FormatTime, FormatDate, FormatDatetime, 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(
|
|
|
+ NewCond(schema.Column, strings.TrimSpace(ss[0])).WithExpr(">="),
|
|
|
+ NewCond(schema.Column, strings.TrimSpace(ss[1])).WithExpr("<="),
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
+ }
|
|
|
+ case FormatInteger, FormatFloat:
|
|
|
query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
+ default:
|
|
|
+ if schema.Type == TypeString {
|
|
|
+ if schema.Attribute.Match == MatchExactly {
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
+ } else {
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, formValue).WithExpr("LIKE"))
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ query.AndFilterWhere(NewCond(schema.Column, formValue))
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|