package api import ( "datart/data/mongo" "datart/log" "errors" "fmt" "strconv" "strings" "github.com/gin-gonic/gin" "github.com/google/uuid" "go.mongodb.org/mongo-driver/v2/bson" ) const ( pageSizeLimit = 500 ) func (a *Api) GetEvents(ctx *gin.Context) { filter, sort, pageNo, pageSize, err := a.checkAndGenGetEventsRequest(ctx) if err != nil { log.Error(err) ctx.JSON(200, gin.H{ "code": 1, "msg": err.Error(), }) return } events, err := mongo.FindEventsWithPageLimit(ctx.Request.Context(), filter, sort, pageNo, pageSize) if err != nil { log.Error(err, fmt.Sprintf(" params: %v, %d, %d, %d", filter, sort, pageNo, pageSize)) ctx.JSON(200, gin.H{ "code": 2, "msg": err.Error(), }) return } ctx.JSON(200, gin.H{ "code": 0, "msg": "success", "data": events, }) } func (a *Api) PostUpsertEvents(ctx *gin.Context) { noUUID, eventUUID, upsert, err := a.checkAndGenUpsertEventsRequest(ctx) if err != nil { log.Error(err) ctx.JSON(200, gin.H{ "code": 1, "msg": err.Error(), }) return } if noUUID { if err = mongo.InsertOneEvent(ctx.Request.Context(), upsert); err != nil { log.Error(err, fmt.Sprintf(" params: %v", upsert)) ctx.JSON(200, gin.H{ "code": 2, "msg": err.Error(), }) return } } else if err = mongo.UpsertOneEvent(ctx.Request.Context(), bson.M{"event_uuid": eventUUID}, bson.M{"$set": bson.M(upsert)}); err != nil { log.Error(err, fmt.Sprintf(" params: %v", upsert)) ctx.JSON(200, gin.H{ "code": 3, "msg": err.Error(), }) return } ctx.JSON(200, gin.H{ "code": 0, "msg": "success", }) } func (a *Api) checkAndGenGetEventsRequest(ctx *gin.Context) (bson.M, int, int64, int64, error) { uuidStr := ctx.Query("uuid") if len(uuidStr) > 0 { if uuid.Validate(uuidStr) != nil { return nil, 0, -1, -1, errors.New("invalid uuid") } return bson.M{"event_uuid": uuidStr}, 0, -1, -1, nil } filter := bson.M{} var err error begin, end := int64(-1), int64(-1) beginStr := ctx.Query("begin") if len(beginStr) > 0 { if begin, err = strconv.ParseInt(beginStr, 10, 64); err != nil { return nil, 0, -1, -1, err } } endStr := ctx.Query("end") if len(endStr) > 0 { if end, err = strconv.ParseInt(endStr, 10, 64); err != nil { return nil, 0, -1, -1, err } } if begin > 0 && end > 0 && begin > end { return nil, 0, -1, -1, errors.New("invalid time") } switch { case begin > 0 && end < 0: filter["timestamp"] = bson.M{"$gte": begin} case begin < 0 && end > 0: filter["timestamp"] = bson.M{"$lte": end} case begin > 0 && end > 0: filter["timestamp"] = bson.M{"$gte": begin, "$lte": end} } statusStr := ctx.Query("status") if len(statusStr) > 0 { statusStrs := strings.Split(statusStr, ",") statuss := make([]int, len(statusStrs)) for i := range statusStrs { s, err := strconv.Atoi(statusStrs[i]) if err != nil { return nil, 0, -1, -1, errors.New("invalid status") } statuss[i] = s } filter["status"] = bson.M{"$in": statuss} } var sort int sortStr := ctx.Query("sort") if len(sortStr) > 0 { s, err := strconv.Atoi(sortStr) if err != nil { return nil, 0, -1, -1, err } if s != 1 && s != -1 { return nil, 0, -1, -1, errors.New("invalid sort") } sort = s } pageNo, pageSize := -1, -1 pageNoStr := ctx.Query("page_no") pageSizeStr := ctx.Query("page_size") if len(pageNoStr) > 0 && len(pageSizeStr) > 0 { pageNo, err = strconv.Atoi(pageNoStr) if err != nil { return nil, 0, -1, -1, err } pageSize, err = strconv.Atoi(pageSizeStr) if err != nil { return nil, 0, -1, -1, err } if pageNo <= 0 || pageSize <= 0 { return nil, 0, -1, -1, errors.New("invalid page param") } if pageSize > pageSizeLimit { pageSize = pageSizeLimit } } return filter, sort, int64(pageNo), int64(pageSize), nil } func (a *Api) checkAndGenUpsertEventsRequest(ctx *gin.Context) (bool, string, map[string]any, error) { e := map[string]any{} err := ctx.ShouldBindJSON(&e) if err != nil { return false, "", nil, errors.New("invalid body param") } eventUUID := "" noUUID := true if eu, ok := e["event_uuid"]; ok { if eUUID, ok := eu.(string); ok { if uuid.Validate(eUUID) == nil { eventUUID = eUUID noUUID = false } } } if noUUID { noUUID = true if uid, err := uuid.NewV7(); err != nil { return false, "", nil, err } else { eventUUID = uid.String() e["event_uuid"] = eventUUID } } return noUUID, eventUUID, e, nil }