/
page.go
180 lines (156 loc) · 4.58 KB
/
page.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//+----------------------------------------------------------------------
// | Copyright (c) 2023 http://www.vuecmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/vuecmf/vuecmf-go/blob/master/LICENSE )
// +----------------------------------------------------------------------
// | Author: vuecmf <tulihua2004@126.com>
// +----------------------------------------------------------------------
package helper
import (
"gorm.io/gorm"
"gorm.io/gorm/schema"
"reflect"
"strings"
)
// ListParams 列表参数
type ListParams struct {
Keywords string `json:"keywords" form:"keywords"` //搜索关键字
OrderField string `json:"order_field" form:"order_field"` //列表排序字段
OrderSort string `json:"order_sort" form:"order_sort"` //字段排序方式 (desc 倒序, asc升序)
Page int `json:"page" form:"page"` //列表当前页码
PageSize int `json:"page_size" form:"page_size"` //列表每页显示条数
Action string `json:"action" form:"action"` //请求动作
Filter map[string]interface{} `json:"filter" form:"filter"` //精确多字段过滤查询
}
// DataListParams 列表参数 用data包裹一下
type DataListParams struct {
Data *ListParams `json:"data" form:"data"`
}
// page 分页结构体
type page struct {
tableName string //模型对应表名
db *gorm.DB //数据库连接实例
ns schema.Namer
filterFields []string //需要模糊查询的字段
group string //分组查询
Fields string //需要查询的字段
}
// result 存放分页列表返回结果
type Result struct {
Data interface{} `json:"data"`
Total int64 `json:"total"`
}
//Field 需要查询的字段
func (p *page) Field(queryFields string) *page {
p.Fields = queryFields
return p
}
//Group 分组查询
func (p *page) Group(name string) *page {
p.group = name
return p
}
// Filter 列表过滤器
// 参数:
// model 模型实例
// params POST请求传递的参数
func (p *page) Filter(model interface{}, data *ListParams) (*Result, error) {
if data.PageSize == 0 {
data.PageSize = 20
}
if data.Page == 0 {
data.Page = 1
}
if data.OrderField == "" {
data.OrderField = "id"
}
offset := (data.Page - 1) * data.PageSize
query := p.db.Table(p.ns.TableName(p.tableName))
if p.Fields != "" {
query = query.Select(p.Fields)
}
query = query.Offset(offset).Limit(data.PageSize)
totalQuery := p.db.Table(p.ns.TableName(p.tableName))
if data.Keywords != "" {
kw := data.Keywords + "%"
for k, field := range p.filterFields {
field = strings.Trim(field, " ")
if k == 0 {
query = query.Where(field+" LIKE ?", kw)
totalQuery = totalQuery.Where(field+" LIKE ?", kw)
} else {
query = query.Or(field+" LIKE ?", kw)
totalQuery = totalQuery.Or(field+" LIKE ?", kw)
}
}
} else if len(data.Filter) > 0 {
//过滤掉空值
for k, v := range data.Filter {
switch val := v.(type) {
case string:
if val == "" {
delete(data.Filter, k)
}
case []string:
if len(val) == 0 {
delete(data.Filter, k)
}
case []interface{}:
if len(val) == 0 {
delete(data.Filter, k)
}
case []int:
if len(val) == 0 {
delete(data.Filter, k)
}
default:
k = strings.ToLower(k)
if k == "not" {
query = query.Not(v)
totalQuery = totalQuery.Not(v)
delete(data.Filter, k)
} else if k == "or" {
query = query.Or(v)
totalQuery = totalQuery.Or(v)
delete(data.Filter, k)
}
}
}
query = query.Where(data.Filter)
totalQuery = totalQuery.Where(data.Filter)
}
if p.group != "" {
query = query.Group(p.group)
totalQuery = totalQuery.Group(p.group)
} else {
query = query.Order(data.OrderField + " " + data.OrderSort)
}
query.Find(model)
var total int64
totalQuery.Count(&total)
res := &Result{
Data: model,
Total: total,
}
return res, nil
}
var pInstances = make(map[string]*page)
// Page 获取列表分页实例
// 参数:
// tableName 模型对应的表名
// db gorm的DB实例指针
// ns gorm数据库相关信息接口
func Page(tableName string, filterFields []string, db *gorm.DB, ns schema.Namer) *page {
p, ok := pInstances[tableName]
if ok == false || !reflect.DeepEqual(p.db, db) {
pInstances[tableName] = &page{
tableName: tableName,
db: db,
ns: ns,
filterFields: filterFields,
}
return pInstances[tableName]
} else {
return p
}
}