| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 | 
							- package svc
 
- import (
 
- 	"encoding/json"
 
- 	"fmt"
 
- 	"net/http"
 
- 	"golib/features/mo"
 
- 	"golib/infra/ii"
 
- 	"golib/network"
 
- )
 
- func NewHTTPHandler(items ii.Items, user ii.User) http.Handler {
 
- 	return &httpHandler{items: items, user: user}
 
- }
 
- const (
 
- 	// Method Post
 
- 	cmdInsertOne  = "insertOne"
 
- 	cmdInsertMany = "insertMany"
 
- 	cmdUpdateOne  = "updateOne"
 
- 	cmdUpdateMany = "updateMany"
 
- 	cmdUpdateById = "updateById"
 
- 	cmdFindOne    = "findOne"
 
- 	cmdFind       = "find"
 
- 	cmdCount      = "count"
 
- 	cmdDeleteOne  = "deleteOne"
 
- 	cmdDeleteMany = "deleteMany"
 
- )
 
- var (
 
- 	actionMap = map[string]struct{}{
 
- 		cmdInsertOne:  {},
 
- 		cmdInsertMany: {},
 
- 		cmdUpdateOne:  {},
 
- 		cmdUpdateMany: {},
 
- 		cmdUpdateById: {},
 
- 		cmdDeleteOne:  {},
 
- 		cmdDeleteMany: {},
 
- 		cmdFind:       {},
 
- 		cmdFindOne:    {},
 
- 		cmdCount:      {},
 
- 	}
 
- )
 
- // action: insertOne/insertMany/updateOne/updateMany/deleteOne/deleteMany/find/findOne
 
- // Request: {"action":"insert", "itemName":"test.test", "fields": {"name":"xiaoming","age":3.1415}}
 
- // Response: {"action":"insert", "itemName": "test.test", "ret":"success", "result":"","fields":{"name":"required"}}
 
- type httpHandleBody struct {
 
- 	CMD      string `json:"cmd"` // CMD 本次请求需要执行的命令
 
- 	ItemName string `json:"itemName"`
 
- 	Data     any    `json:"data"` // Data 数据类型根据 action 变化
 
- 	ExtData  any    `json:"extData"`
 
- }
 
- type httpHandler struct {
 
- 	items ii.Items
 
- 	user  ii.User
 
- }
 
- func (f *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
- 	cmd, itemName, err := splitPATH(r.URL.Path, "svc")
 
- 	if err != nil {
 
- 		http.Error(w, err.Error(), http.StatusForbidden)
 
- 		return
 
- 	}
 
- 	if _, ok := actionMap[cmd]; !ok {
 
- 		http.Error(w, "unknown cmd", http.StatusNotFound)
 
- 		return
 
- 	}
 
- 	if _, ok := f.items.Has(itemName); !ok {
 
- 		http.Error(w, ErrItemNotfound.Error(), http.StatusNotFound)
 
- 		return
 
- 	}
 
- 	b, err := network.HTTP.ReadRequestBody(w, r, 4096)
 
- 	if err != nil {
 
- 		network.HTTP.Error(w, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	var hrb httpHandleBody
 
- 	if err = json.Unmarshal(b, &hrb); err != nil {
 
- 		network.HTTP.Error(w, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	hrb.ItemName = itemName
 
- 	hrb.CMD = cmd
 
- 	switch hrb.CMD {
 
- 	case cmdInsertOne:
 
- 		f.handleInsertOne(w, &hrb)
 
- 	case cmdInsertMany:
 
- 		f.handleInsertMany(w, &hrb)
 
- 	case cmdUpdateOne:
 
- 		f.handleUpdateOne(w, &hrb)
 
- 	case cmdUpdateMany:
 
- 		f.handleUpdateMany(w, &hrb)
 
- 	case cmdUpdateById:
 
- 		f.handleUpdateByID(w, &hrb)
 
- 	case cmdDeleteOne:
 
- 		f.handleDeleteOne(w, &hrb)
 
- 	case cmdDeleteMany:
 
- 		f.handleDeleteMany(w, &hrb)
 
- 	case cmdFindOne:
 
- 		f.handleFindOne(w, &hrb)
 
- 	case cmdFind:
 
- 		f.handleFind(w, &hrb)
 
- 	case cmdCount:
 
- 		f.handleCount(w, &hrb)
 
- 	}
 
- }
 
- func (f *httpHandler) handleFind(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	filter, err := f.handleFilterData(hrb.Data)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	rows, err := Svc(f.user).Find(hrb.ItemName, filter)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     rows,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleFindOne(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	filter, err := f.handleFilterData(hrb.Data)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	row, err := Svc(f.user).FindOne(hrb.ItemName, filter)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     row,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleInsertOne(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	data, ok := hrb.Data.(map[string]interface{})
 
- 	if !ok {
 
- 		f.respJsonErr(w, ErrDataError, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	oid, err := Svc(f.user).InsertOne(hrb.ItemName, data)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     oid,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleInsertMany(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	data, ok := hrb.Data.([]interface{})
 
- 	if !ok {
 
- 		f.respJsonErr(w, ErrDataError, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	oidList, err := Svc(f.user).InsertMany(hrb.ItemName, data)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     oidList,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleUpdateOne(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	filter, update, err := f.handleUpdateData(hrb)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	if err = Svc(f.user).UpdateOne(hrb.ItemName, filter, update); err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     nil,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleUpdateByID(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	idStr, ok := hrb.Data.(string)
 
- 	if !ok {
 
- 		f.respJsonErr(w, ErrDataError, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	oid, err := mo.ID.From(idStr)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, ErrDataError, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	update, ok := hrb.ExtData.(map[string]interface{})
 
- 	if !ok {
 
- 		f.respJsonErr(w, ErrDataError, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	if err = Svc(f.user).UpdateByID(hrb.ItemName, oid, update); err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     nil,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleUpdateMany(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	filter, update, err := f.handleUpdateData(hrb)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	if err = Svc(f.user).UpdateMany(hrb.ItemName, filter, update); err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     nil,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleCount(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	var (
 
- 		total int64
 
- 		err   error
 
- 	)
 
- 	if hrb.Data == nil || hrb.Data == "" {
 
- 		total, err = Svc(f.user).EstimatedDocumentCount(hrb.ItemName)
 
- 	} else {
 
- 		filter, err := f.handleFilterData(hrb.Data)
 
- 		if err != nil {
 
- 			f.respJsonErr(w, err, http.StatusBadRequest)
 
- 			return
 
- 		}
 
- 		total, err = Svc(f.user).CountDocuments(hrb.ItemName, filter)
 
- 	}
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     total,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleDeleteOne(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	filter, err := f.handleFilterData(hrb.Data)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	if err = Svc(f.user).DeleteOne(hrb.ItemName, filter); err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     nil,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleDeleteMany(w http.ResponseWriter, hrb *httpHandleBody) {
 
- 	filter, err := f.handleFilterData(hrb.Data)
 
- 	if err != nil {
 
- 		f.respJsonErr(w, err, http.StatusBadRequest)
 
- 		return
 
- 	}
 
- 	if err = Svc(f.user).DeleteMany(hrb.ItemName, filter); err != nil {
 
- 		f.respJsonErr(w, err, http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	resp := &httpHandleBody{
 
- 		CMD:      hrb.CMD,
 
- 		ItemName: hrb.ItemName,
 
- 		Data:     nil,
 
- 	}
 
- 	f.respJson(w, resp)
 
- }
 
- func (f *httpHandler) handleUpdateData(hrb *httpHandleBody) (mo.D, mo.M, error) {
 
- 	filter, err := f.handleFilterData(hrb.Data)
 
- 	if err != nil {
 
- 		return nil, nil, err
 
- 	}
 
- 	update, ok := hrb.ExtData.(map[string]interface{})
 
- 	if !ok {
 
- 		return nil, nil, err
 
- 	}
 
- 	return filter, update, nil
 
- }
 
- func (f *httpHandler) handleFilterData(data any) (mo.D, error) {
 
- 	b, err := mo.MarshalExtJSON(data, false, true)
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	var filter mo.D
 
- 	if err = mo.UnmarshalExtJSON(b, false, &filter); err != nil {
 
- 		return nil, err
 
- 	}
 
- 	return filter, nil
 
- }
 
- func (f *httpHandler) respJson(w http.ResponseWriter, v interface{}) {
 
- 	p, err := json.Marshal(v)
 
- 	if err != nil {
 
- 		http.Error(w, err.Error(), http.StatusInternalServerError)
 
- 		return
 
- 	}
 
- 	w.Header().Set("Content-Type", network.HTTPContentTypeJson)
 
- 	w.WriteHeader(http.StatusOK)
 
- 	_, _ = w.Write(p)
 
- }
 
- func (f *httpHandler) respJsonErr(w http.ResponseWriter, err error, code int) {
 
- 	w.Header().Set("Content-Type", network.HTTPContentTypeJson)
 
- 	w.WriteHeader(code)
 
- 	_, _ = w.Write([]byte(fmt.Sprintf(`{"result":"%s"}`, err)))
 
- }
 
 
  |