curd.go 4.9 KB
Newer Older
1 2 3
package api

import (
4
	"encoding/json"
5
	"git.zgwit.com/zgwit/iot-admin/db"
6 7 8
	"github.com/gorilla/mux"
	"io/ioutil"
	"net/http"
9
	"reflect"
10
	"strconv"
11 12
)

J
Jason 已提交
13
type hook func(value interface{}) error
14

J
Jason 已提交
15 16 17 18 19 20 21 22 23 24
func createSliceFromType(mod reflect.Type) interface{} {
	//datas := reflect.MakeSlice(reflect.SliceOf(mod), 0, 10).Interface()

	//解决不可寻址的问题,参考modern-go/reflect2 safe_slice.go
	val := reflect.MakeSlice(reflect.SliceOf(mod), 0, 1)
	ptr := reflect.New(val.Type())
	ptr.Elem().Set(val)
	return ptr.Interface()
}

25 26 27 28 29 30 31 32 33 34 35 36
func parseBody(request *http.Request, data interface{}) error  {
	body, err := ioutil.ReadAll(request.Body)
	if err != nil {
		return err
	}
	return json.Unmarshal(body, data)
}

type Handler func(writer http.ResponseWriter, request *http.Request)

func curdApiList(mod reflect.Type) Handler {
	return func(writer http.ResponseWriter, request *http.Request) {
J
Jason 已提交
37 38 39
		datas := createSliceFromType(mod)

		var body paramSearch
40
		err := parseBody(request, &body)
J
Jason 已提交
41
		if err != nil {
42
			replyError(writer, err)
J
Jason 已提交
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
			return
		}

		op := db.Engine.Limit(body.Length, body.Offset)

		for _, filter := range body.Filters {
			if len(filter.Values) > 0 {
				if len(filter.Values) == 1 {
					op.And(filter.Key+"=?", filter.Values[0])
				} else {
					op.In(filter.Key, filter.Values)
				}
			}
		}
		if body.Keyword != "" {
			kw := "%" + body.Keyword + "%"
			op.And("user like ? or text like ? or file like ?", kw, kw, kw)
		}

		if body.SortKey != "" {
			if body.SortOrder == "desc" {
				op.Desc(body.SortKey)
			} else {
				op.Asc(body.SortKey)
			}
		} else {
			op.Desc("id")
		}
		cnt, err := op.FindAndCount(datas)
		if err != nil {
73
			replyError(writer, err)
J
Jason 已提交
74 75 76 77
			return
		}

		//replyOk(ctx, cs)
78
		replyList(writer, datas, cnt)
J
Jason 已提交
79 80
	}
}
81

82 83
func curdApiListById(mod reflect.Type, field string) Handler {
	return func(writer http.ResponseWriter, request *http.Request) {
J
Jason 已提交
84
		datas := createSliceFromType(mod)
85

86
		id, err := strconv.ParseInt(mux.Vars(request)["id"], 10, 64)
87
		if err != nil {
88
			replyError(writer, err)
J
Jason 已提交
89 90
			return
		}
91 92

		var body paramSearch
93
		err = parseBody(request, &body)
94
		if err != nil {
95
			replyError(writer, err)
96 97 98
			return
		}

99
		op := db.Engine.Where(field+"=?", id).Limit(body.Length, body.Offset)
100 101

		for _, filter := range body.Filters {
J
Jason 已提交
102 103 104
			if len(filter.Values) > 0 {
				if len(filter.Values) == 1 {
					op.And(filter.Key+"=?", filter.Values[0])
105
				} else {
J
Jason 已提交
106
					op.In(filter.Key, filter.Values)
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
				}
			}
		}
		if body.Keyword != "" {
			kw := "%" + body.Keyword + "%"
			op.And("user like ? or text like ? or file like ?", kw, kw, kw)
		}

		if body.SortKey != "" {
			if body.SortOrder == "desc" {
				op.Desc(body.SortKey)
			} else {
				op.Asc(body.SortKey)
			}
		} else {
			op.Desc("id")
		}
124
		cnt, err := op.FindAndCount(datas)
125
		if err != nil {
126
			replyError(writer, err)
127 128 129 130
			return
		}

		//replyOk(ctx, cs)
131
		replyList(writer, datas, cnt)
132 133 134
	}
}

135 136
func curdApiCreate(mod reflect.Type, after hook) Handler {
	return func(writer http.ResponseWriter, request *http.Request) {
J
Jason 已提交
137
		data := reflect.New(mod).Interface()
138 139
		if err := parseBody(request, data); err != nil {
			replyError(writer, err)
140 141 142
			return
		}

J
Jason 已提交
143
		_, err := db.Engine.Insert(data)
144
		if err != nil {
145
			replyError(writer, err)
146 147
			return
		}
J
Jason 已提交
148 149

		if after != nil {
J
Jason 已提交
150
			err = after(data)
J
Jason 已提交
151
			if err != nil {
152
				replyError(writer, err)
J
Jason 已提交
153 154 155 156
				return
			}
		}

157
		replyOk(writer, data)
158 159 160
	}
}

161 162 163
func curdApiModify(mod reflect.Type, updateFields []string, after hook) Handler {
	return func(writer http.ResponseWriter, request *http.Request) {
		id, err := strconv.ParseInt(mux.Vars(request)["id"], 10, 64)
164
		if err != nil {
165
			replyError(writer, err)
166 167 168
			return
		}

J
Jason 已提交
169
		data := reflect.New(mod).Interface()
170 171
		if err := parseBody(request, data); err != nil {
			replyError(writer, err)
172 173 174
			return
		}

175
		_, err = db.Engine.ID(id).Cols(updateFields...).Update(data)
176
		if err != nil {
177
			replyError(writer, err)
178 179 180
			return
		}

J
Jason 已提交
181
		if after != nil {
J
Jason 已提交
182
			err = after(data)
J
Jason 已提交
183
			if err != nil {
184
				replyError(writer, err)
J
Jason 已提交
185 186 187 188
				return
			}
		}

189
		replyOk(writer, data)
190 191 192
	}
}

193 194 195
func curdApiDelete(mod reflect.Type, after hook) Handler {
	return func(writer http.ResponseWriter, request *http.Request) {
		id, err := strconv.ParseInt(mux.Vars(request)["id"], 10, 64)
196
		if err != nil {
197
			replyError(writer, err)
198 199 200
			return
		}

J
Jason 已提交
201
		data := reflect.New(mod).Interface()
202
		_, err = db.Engine.ID(id).Delete(data)
203
		if err != nil {
204
			replyError(writer, err)
205 206
			return
		}
J
Jason 已提交
207 208

		if after != nil {
J
Jason 已提交
209
			err = after(data)
J
Jason 已提交
210
			if err != nil {
211
				replyError(writer, err)
J
Jason 已提交
212 213 214 215
				return
			}
		}

216
		replyOk(writer, nil)
217 218 219
	}
}

220 221 222
func curdApiGet(mod reflect.Type) Handler {
	return func(writer http.ResponseWriter, request *http.Request) {
		id, err := strconv.ParseInt(mux.Vars(request)["id"], 10, 64)
223
		if err != nil {
224
			replyError(writer, err)
225 226
			return
		}
J
Jason 已提交
227
		data := reflect.New(mod).Interface()
228
		has, err := db.Engine.ID(id).Get(data)
229
		if !has {
230
			replyFail(writer, "记录不存在")
231 232
			return
		} else if err != nil {
233
			replyError(writer, err)
234 235
			return
		}
236
		replyOk(writer, data)
237 238
	}
}