| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | 
							- package bootable
 
- import (
 
- 	"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/post
 
- func (q *Filter) Build(itemInfo ii.ItemInfo, items ii.Items) (mo.Pipeline, error) {
 
- 	p := mo.Pipeline{}
 
- 	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())
 
- 	}
 
- 	if q.Order != "" {
 
- 		p = append(p, q.ParseSorter())
 
- 	}
 
- 	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()
 
- }
 
 
  |