package api import ( "encoding/hex" "fmt" "mesh/db/repo" "reflect" "github.com/gin-gonic/gin" "go.mongodb.org/mongo-driver/bson/primitive" ) type CreateModel func(c *gin.Context, apictx *ApiSession) (interface{}, error) type EmptyModel func(c *gin.Context, apictx *ApiSession) interface{} type CreateModel2 func(c *gin.Context, apictx *ApiSession) (interface{}, error) type SearchFilterFn func(c *gin.Context, apictx *ApiSession, query map[string]interface{}) map[string]interface{} type Update func(c *gin.Context, apictx *ApiSession, entity interface{}) type SearchPostFn func(page *repo.PageResult, c *gin.Context, apictx *ApiSession, query map[string]interface{}) (interface{}, error) type RemoveFn func(c *gin.Context, apictx *ApiSession, id string) (interface{}, error) type CRUDOption struct { Collection string NewModel CreateModel EmtyModel EmptyModel SearchFilter SearchFilterFn SearchPostProcess SearchPostFn SearchSort interface{} Remove RemoveFn JWT bool SearchProject []string DetailProject []string OnUpdate Update noUpdate bool } func CreateCRUD(router *GinRouter, prefix string, option *CRUDOption) { //创建 if option.NewModel != nil { creatpath := fmt.Sprintf("%s/create", prefix) router.POSTJWT(creatpath, func(c *gin.Context, apictx *ApiSession) (interface{}, error) { entity, err := option.NewModel(c, apictx) if err != nil { return nil, err } if entity == nil { return nil, NewError("数据已存在!") } return repo.RepoAddDoc(apictx.CreateRepoCtx(), option.Collection, entity) }) } //更新 if !option.noUpdate { updatePath := fmt.Sprintf("%s/update", prefix) router.POSTJWT(updatePath, func(c *gin.Context, apictx *ApiSession) (interface{}, error) { m := option.EmtyModel(c, apictx) err := c.ShouldBindJSON(m) if err != nil { fmt.Println(err) return nil, NewError("参数解析错误") } v := reflect.ValueOf(m) v = v.Elem() mid := v.FieldByName("Id") if !mid.IsValid() { return nil, NewError("ID不能为空") } slice := mid.Slice(0, mid.Len()) objId := hex.EncodeToString(slice.Bytes()) for i := 0; i < 12; i++ { mid.Index(i).SetUint(0) } if option.OnUpdate != nil { option.OnUpdate(c, apictx, m) } out, err := repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), option.Collection, objId, m) if err != nil { return nil, err } if out.MatchedCount != 1 { return nil, NewError("文件不存在!") } return out, nil }) } //分页查询 SearchPath := fmt.Sprintf("%s/list", prefix) pageSearchFn := func(c *gin.Context, apictx *ApiSession) (interface{}, error) { page, size, query := UtilQueryPageSize(c) if option.SearchFilter != nil { filter := option.SearchFilter(c, apictx, query) for k, v := range filter { query[k] = v } } pageOption := &repo.PageSearchOptions{ CollectName: option.Collection, Page: page, Size: size, Query: query, Project: option.SearchProject, } if option.SearchSort != nil { pageOption.Sort = option.SearchSort } pageResult, err := repo.RepoPageSearch(apictx.CreateRepoCtx(), pageOption) if err != nil { return nil, err } if option.SearchPostProcess != nil { return option.SearchPostProcess(pageResult, c, apictx, query) } return pageResult, nil } if option.JWT { router.GETJWT(SearchPath, pageSearchFn) } else { router.GET(SearchPath, pageSearchFn) } //删除 removePath := fmt.Sprintf("%s/delete/:id", prefix) router.POSTJWT(removePath, func(c *gin.Context, apictx *ApiSession) (interface{}, error) { id := c.Param("id") if len(id) < 1 { return nil, NewError("参数不能为空") } if option.Remove != nil { return option.Remove(c, apictx, id) } return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), option.Collection, id) }) //详情 if len(option.DetailProject) > 0 { detailPath := fmt.Sprintf("%s/detail/:id", prefix) router.GET(detailPath, func(c *gin.Context, apictx *ApiSession) (interface{}, error) { id := c.Param("id") if len(id) < 1 { return nil, NewError("参数不能为空") } uid, _ := primitive.ObjectIDFromHex(id) ok, ret := repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: option.Collection, Query: repo.Map{"_id": uid}, Project: option.DetailProject, }) if !ok { return nil, NewError("没有查询到数据") } return ret, nil }) } }