| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | package bootableimport (	"golib/features/mo"	"golib/infra/ii")type Response struct {	Rows  []mo.M `json:"rows"`	Total int64  `json:"total"`	Ret   string `json:"ret"`}// Filter 查询参数type Filter struct {	Limit   int64  `json:"limit,omitempty"`	Offset  int64  `json:"offset,omitempty"`	ExtName string `json:"name,omitempty"`   // ExtName 用于 Search	Search  string `json:"search,omitempty"` // Search 用于 Toolbar search	Sort    string `json:"sort,omitempty"`   // Field ID	Order   string `json:"order,omitempty"`  // ASC/DESC	Filter  string `json:"filter,omitempty"` // Filter 用于 filter control	Custom  mo.D   `bson:"custom,omitempty"` // Custom 自定义查询条件, 使用 bson, 支持 MongoDB json 查询语法	lookASName []string}const (	TimeLayout = "2006-01-02")// Build 解析查询参数, 当 Search 和 Filter 同时存在时, Filter 生效// 该方法需要设置为 ajax/postfunc (q *Filter) Build(itemInfo ii.ItemInfo, items ii.Items) (mo.Pipeline, error) {	p := mo.Pipeline{}	if q.Order != "" {		p = append(p, q.ParseSorter())	}	matcher := mo.Matcher{}	// 请求查询条件	if len(q.Custom) > 0 {		q.handleParams(&itemInfo, items, &p, &matcher, q.Custom, true)	}	// filter 查询条件	// 将 json 字符串使用轻松模式解析为 mo.D 以便保持 json 结构字段顺序	var doc mo.D	if q.Filter != "" {		if err := mo.UnmarshalExtJSON([]byte(q.Filter), false, &doc); err != nil {			return nil, err		}	} else if q.Search != "" {		doc = append(doc, mo.E{Key: q.ExtName, Value: q.Search})	}	q.handleParams(&itemInfo, items, &p, &matcher, doc, false)	if done := matcher.Done(); len(done) > 0 {		p = append(p, matcher.Pipeline())	}	arg, err := itemInfo.Aggregation(items)	if err != nil {		return nil, err	}	if len(arg) > 0 {		if len(q.lookASName) == 0 {			p = append(p, arg...)		} else {			// 循环每一个 arg 内的元素			for _, ele := range arg {				// MongoDB 要求聚合操作符作为 Key, 因此此次判断 key 即可. 通常聚合操作中 mo.D 内只有一个元素, 所以直接取第 1 和元素				// 如果非 Lookup 聚合操作则跳过				if ele[0].Key != mo.PsLookup {					p = append(p, ele)					continue				}				// 获取 Lookup.AS, 此处无法获取到请求的 FieldName, 由于 Lookup.As 在 itemInfo 中也是唯一的, 并且和 FieldName 是绑定的, 所以使用 Lookup.AS 替代				as := ele[0].Value.(mo.D).Map()["as"]				// 如果前端已传入 Lookup 查找, 则不再添加 XML 内的 Lookup				for _, name := range q.lookASName {					if name != as {						p = append(p, ele)					}				}			}		}	}	if q.Offset > 0 {		p = append(p, mo.NewSkip(q.Offset).Pipeline())	}	if q.Limit > 0 {		p = append(p, mo.NewLimiter(q.Limit).Pipeline())	}	return p, nil}func (q *Filter) ParseSorter() mo.D {	if q.Order == "asc" {		return (&mo.Sorter{}).AddASC(q.Sort).Pipeline()	}	return (&mo.Sorter{}).AddDESC(q.Sort).Pipeline()}
 |