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  }