github.com/zooyer/miskit@v1.0.71/micro/dto.go (about) 1 package micro 2 3 import ( 4 "fmt" 5 "net/url" 6 "reflect" 7 "strings" 8 9 "github.com/gin-gonic/gin" 10 "gorm.io/gorm" 11 ) 12 13 type Query struct { 14 form url.Values // 自定义字段 15 16 Page int `form:"page" json:"page,omitempty"` // 当前页 17 Size int `form:"size" json:"size,omitempty"` // 页大小 18 Sort string `form:"sort" json:"sort,omitempty"` // 排序 19 Cond string `form:"cond" json:"cond,omitempty"` // 条件符号:and、or,用于自定义字段查询 20 Omit []string `form:"omit" json:"omit,omitempty"` // 忽略字段 21 Select []string `form:"select" json:"select,omitempty"` // 选择字段 22 Where string `form:"where" json:"where,omitempty"` // 自定义条件SQL 23 } 24 25 type Result struct { 26 Query 27 Count int `json:"count"` 28 Total int64 `json:"total"` 29 Data interface{} `json:"data"` 30 } 31 32 var omitParams = make(map[string]bool) 33 34 func init() { 35 t := reflect.TypeOf(Query{}) 36 for i := 0; i < t.NumField(); i++ { 37 tag := t.Field(i).Tag.Get("form") 38 if tag == "" { 39 tag = t.Field(i).Tag.Get("json") 40 tag = strings.Split(tag, ",")[0] 41 } 42 omitParams[tag] = true 43 } 44 } 45 46 func (q *Query) BySelect(db *gorm.DB) *gorm.DB { 47 if len(q.Select) > 0 { 48 db = db.Select(q.Select) 49 } 50 51 if len(q.Omit) > 0 { 52 db = db.Omit(q.Omit...) 53 } 54 55 return db 56 } 57 58 func (q *Query) ByLimit(db *gorm.DB) *gorm.DB { 59 if q.Page > 0 { 60 db = db.Offset((q.Page - 1) * q.Size) 61 } 62 63 return db.Limit(q.Size) 64 } 65 66 func (q *Query) BySort(db *gorm.DB) *gorm.DB { 67 return db.Order(q.Sort) 68 } 69 70 func (q *Query) ByWhere(db *gorm.DB) *gorm.DB { 71 if q.Where != "" { 72 db = db.Where(q.Where) 73 } 74 return db 75 } 76 77 func (q *Query) ByCustom(db *gorm.DB) *gorm.DB { 78 var ( 79 query string 80 args []interface{} 81 isFirst = true 82 ) 83 84 for key, val := range q.form { 85 if omitParams[key] || len(val) == 0 || len(val) == 1 && len(val[0]) == 0 { 86 continue 87 } 88 89 var op byte // 查询匹配符(^前缀匹配, $后缀匹配, *模糊匹配, =等值匹配, 默认数组匹配) 90 if len(val) == 1 && len(val[0]) > 1 { 91 switch o := val[0][0]; o { 92 case '^', '$', '*', '=', '\\': 93 op = o 94 val = []string{val[0][1:]} 95 } 96 } 97 98 // 查询条件 99 if isFirst { 100 isFirst = false 101 } else { 102 switch q.Cond { 103 case "or": 104 query += " OR " 105 case "and": 106 query += " AND " 107 case "not": 108 query += " NOT " 109 default: 110 query += " AND " 111 } 112 } 113 114 switch op { 115 case '^': // 前缀匹配 116 query += fmt.Sprintf("%s LIKE ?", key) 117 args = append(args, fmt.Sprintf("%s%%", val[0])) 118 case '$': // 后缀匹配 119 query += fmt.Sprintf("%s LIKE ?", key) 120 args = append(args, fmt.Sprintf("%%%s", val[0])) 121 case '*': // 模糊匹配 122 query += fmt.Sprintf("%s LIKE ?", key) 123 args = append(args, fmt.Sprintf("%%%s%%", val[0])) 124 case '=': // 等值匹配 125 query += fmt.Sprintf("`%s` = ?", key) 126 args = append(args, val[0]) 127 case '\\': 128 fallthrough 129 default: // 数组匹配 (没有操作符或是数组全部是等值匹配) 130 query += fmt.Sprintf("%s IN (?)", key) 131 args = append(args, val) 132 } 133 } 134 135 return db.Where(query, args...) 136 } 137 138 func (q *Query) ByQuery(db *gorm.DB) *gorm.DB { 139 return db.Scopes(q.BySelect, q.ByWhere, q.ByCustom, q.ByLimit, q.BySort) 140 } 141 142 func (q *Query) Valid(ctx *gin.Context) (err error) { 143 if q.Size == 0 { 144 q.Size = 100 145 } 146 147 if q.Sort == "" { 148 q.Sort = "id DESC" 149 } 150 151 if err = ctx.Request.ParseForm(); err != nil { 152 return 153 } 154 155 q.form = make(url.Values) 156 for key, val := range ctx.Request.Form { 157 if !omitParams[key] { 158 q.form[key] = val 159 } 160 } 161 162 return 163 }