diff --git a/api/consts/option.go b/api/consts/option.go index 9543f362..78ab15a9 100644 --- a/api/consts/option.go +++ b/api/consts/option.go @@ -100,8 +100,3 @@ const ( ) const ZoneAdmissionPrice_NoZone = int64(-999999) - -const ( - RavenIQTestVisit_PV = 0 - RavenIQTestVisit_UV = 1 -) diff --git a/api/consts/status.go b/api/consts/status.go index 47d7dbcd..bc706c6c 100644 --- a/api/consts/status.go +++ b/api/consts/status.go @@ -328,3 +328,15 @@ const ( Email_Success = 1 // 已发送 Email_Fail = 2 // 发送失败 ) + +// 瑞文智商测试c_type +const ( + RavenIQTest_CType_PV = 0 // pv + RavenIQTest_CType_UV = 1 // uv +) + +// 瑞文智商测试v_type +const ( + RavenIQTest_VType_Visit = 0 // 访问 + RavenIQTest_VType_Paid = 1 // 付款 +) diff --git a/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_api.go b/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_api.go index 51fa2b68..37605e4e 100644 --- a/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_api.go +++ b/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_api.go @@ -54,14 +54,15 @@ type ApiListResp struct { // op 计数 type ApiCountReq struct { base.BaseRequest - VType *int64 `json:"v_type" bson:"v_type"` // 访问类型 CType *int64 `json:"c_type" bson:"c_type"` // 计数类型 CtLowerBound *int64 `json:"ct_lb" bson:"ct_lb"` // 访问时间下界 CtUpperBound *int64 `json:"ct_ub" bson:"ct_ub"` // 访问时间上界 } type ApiCountData struct { - Count int64 `json:"count" bson:"count"` + VisitCount int64 `json:"visit_count" bson:"visit_count"` + PaidCount int64 `json:"paid_count" bson:"paid_count"` + TotalCount int64 `json:"total_count" bson:"total_count"` } type ApiCountResp struct { diff --git a/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_op.go b/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_op.go index ec3280d2..70a9dbe2 100644 --- a/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_op.go +++ b/api/proto/Raven_IQ_test_visit/proto/Raven_IQ_test_visit_op.go @@ -36,10 +36,8 @@ type OpDeleteResp struct { // op 计数 type OpCountReq struct { base.BaseRequest - VType *int64 `json:"v_type" bson:"v_type"` // 访问类型 - CType *int64 `json:"c_type" bson:"c_type"` // 计数类型 - CtLowerBound *int64 `json:"ct_lb" bson:"ct_lb"` // 访问时间下界 - CtUpperBound *int64 `json:"ct_ub" bson:"ct_ub"` // 访问时间上界 + CtLowerBound *int64 `json:"ct_lb" bson:"ct_lb"` // 访问时间下界 + CtUpperBound *int64 `json:"ct_ub" bson:"ct_ub"` // 访问时间上界 } type OpCountData struct { diff --git a/api/proto/Raven_IQ_test_visit/proto/not_null_def_api.go b/api/proto/Raven_IQ_test_visit/proto/not_null_def_api.go index de782944..ba121256 100644 --- a/api/proto/Raven_IQ_test_visit/proto/not_null_def_api.go +++ b/api/proto/Raven_IQ_test_visit/proto/not_null_def_api.go @@ -16,7 +16,6 @@ func (p *ApiCreateReq) ProvideNotNullValue() (params []*validator.JsonParam) { // op 计数 func (p *ApiCountReq) ProvideNotNullValue() (params []*validator.JsonParam) { params = make([]*validator.JsonParam, 0) - params = append(params, validator.NewInt64PtrParam("请确认访问类型", p.VType)) params = append(params, validator.NewInt64PtrParam("请确认计数类型", p.CType)) return } diff --git a/app/mix/controller/Raven_IQ_test_visit_api.go b/app/mix/controller/Raven_IQ_test_visit_api.go index 2492f125..42886c9e 100644 --- a/app/mix/controller/Raven_IQ_test_visit_api.go +++ b/app/mix/controller/Raven_IQ_test_visit_api.go @@ -1,6 +1,7 @@ package controller import ( + "service/api/consts" "service/api/errcode" Raven_IQ_test_visitproto "service/api/proto/Raven_IQ_test_visit/proto" "service/app/mix/service" @@ -24,7 +25,7 @@ func ApiCreateRavenIQTestVisit(ctx *gin.Context) { func ApiGetRavenIQTestVisitCount(ctx *gin.Context) { req := ctx.MustGet("client_req").(*Raven_IQ_test_visitproto.ApiCountReq) - count, ec := service.DefaultService.ApiGetRavenIQTestVisitCount(ctx, req) + countMap, ec := service.DefaultService.ApiGetRavenIQTestVisitCount(ctx, req) if ec != errcode.ErrCodeRavenIQTestVisitSrvOk { logger.Error("ApiCreateRavenIQTestVisit fail, req: %v, ec: %v", util.ToJson(req), ec) ReplyErrCodeMsg(ctx, ec) @@ -32,7 +33,9 @@ func ApiGetRavenIQTestVisitCount(ctx *gin.Context) { } data := &Raven_IQ_test_visitproto.ApiCountData{ - Count: count, + VisitCount: countMap[consts.RavenIQTest_VType_Visit], + PaidCount: countMap[consts.RavenIQTest_VType_Paid], + TotalCount: countMap[consts.RavenIQTest_VType_Visit] + countMap[consts.RavenIQTest_VType_Paid], } ReplyOk(ctx, data) diff --git a/app/mix/dao/mongo.go b/app/mix/dao/mongo.go index f399a526..e5511fad 100644 --- a/app/mix/dao/mongo.go +++ b/app/mix/dao/mongo.go @@ -6339,39 +6339,98 @@ func (m *Mongo) DeleteRavenIQTestVisit(ctx *gin.Context, id int64) error { return err } -func (m *Mongo) GetRavenIQTestVisitCount(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (int64, error) { +func (m *Mongo) GetRavenIQTestVisitPV(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (results []map[string]any, err error) { col := m.getColRavenIQTestVisit() - filterInClause := []qmgo.M{} - if req.CtLowerBound != nil { - filterInClause = append(filterInClause, qmgo.M{ - "ct": qmgo.M{ - "$gte": util.DerefInt64(req.CtLowerBound), - }, - }) - } - if req.CtUpperBound != nil { - filterInClause = append(filterInClause, qmgo.M{ - "ct": qmgo.M{ - "$lte": util.DerefInt64(req.CtUpperBound), - }, - }) - } - - if len(filterInClause) == 0 { - return 0, nil - } - - query := qmgo.M{ - "v_type": util.DerefInt64(req.VType), - "$and": filterInClause, + filterClause := qmgo.M{ "del_flag": 0, } - - if util.DerefInt64(req.CType) == consts.RavenIQTestVisit_PV { - return col.Find(ctx, query).Count() - } else if util.DerefInt64(req.CType) == consts.RavenIQTestVisit_UV { - return col.Find(ctx, query).Count() + ctClause := qmgo.M{} + if req.CtLowerBound != nil { + ctClause["$gte"] = util.DerefInt64(req.CtLowerBound) } - return 0, nil + if req.CtUpperBound != nil { + ctClause["$lte"] = util.DerefInt64(req.CtUpperBound) + } + + if len(ctClause) > 0 { + filterClause["ct"] = ctClause + } + + matchClause := bson.D{{ + Key: "$match", Value: filterClause, + }} + + groupClause := bson.D{ + {Key: "$group", Value: bson.D{ + {Key: "_id", Value: "$v_type"}, + {Key: "pv", Value: bson.M{ + "$sum": 1, + }}, + }, + }, + } + + pipeline := qmgo.Pipeline{matchClause, groupClause} + + err = col.Aggregate(ctx, pipeline).All(&results) + if err != nil { + logger.Error("err : %v", err) + return + } + + return +} + +func (m *Mongo) GetRavenIQTestVisitUV(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (results []map[string]any, err error) { + col := m.getColRavenIQTestVisit() + + filterClause := qmgo.M{ + "del_flag": 0, + } + ctClause := qmgo.M{} + if req.CtLowerBound != nil { + ctClause["$gte"] = util.DerefInt64(req.CtLowerBound) + } + if req.CtUpperBound != nil { + ctClause["$lte"] = util.DerefInt64(req.CtUpperBound) + } + + if len(ctClause) > 0 { + filterClause["ct"] = ctClause + } + + matchClause := bson.D{{ + Key: "$match", Value: filterClause, + }} + + distinctClause := bson.D{ + {Key: "$group", Value: bson.D{ + {Key: "_id", Value: bson.M{ + "v_type": "$v_type", + "user_id": "$user_id", + }}, + }, + }, + } + + groupClause := bson.D{ + {Key: "$group", Value: bson.D{ + {Key: "_id", Value: "$_id.v_type"}, + {Key: "uv", Value: bson.M{ + "$sum": 1, + }}, + }, + }, + } + + pipeline := qmgo.Pipeline{matchClause, distinctClause, groupClause} + + err = col.Aggregate(ctx, pipeline).All(&results) + if err != nil { + logger.Error("err : %v", err) + return + } + + return } diff --git a/app/mix/service/apiservice.go b/app/mix/service/apiservice.go index 09dad22d..9f0c6735 100644 --- a/app/mix/service/apiservice.go +++ b/app/mix/service/apiservice.go @@ -4315,16 +4315,22 @@ func (s *Service) ApiCreateRavenIQTestVisit(ctx *gin.Context, req *Raven_IQ_test return } -func (s *Service) ApiGetRavenIQTestVisitCount(ctx *gin.Context, req *Raven_IQ_test_visitproto.ApiCountReq) (count int64, ec errcode.ErrCode) { +func (s *Service) ApiGetRavenIQTestVisitCount(ctx *gin.Context, req *Raven_IQ_test_visitproto.ApiCountReq) (countMap map[int64]int64, ec errcode.ErrCode) { ec = errcode.ErrCodeRavenIQTestVisitSrvOk - count, err := _DefaultRavenIQTestVisit.OpCount(ctx, &Raven_IQ_test_visitproto.OpCountReq{ - VType: req.VType, - CType: req.CType, + + var countFunc func(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (map[int64]int64, error) + if util.DerefInt64(req.CType) == consts.RavenIQTest_CType_PV { + countFunc = _DefaultRavenIQTestVisit.OpCountPV + } else { + countFunc = _DefaultRavenIQTestVisit.OpCountUV + } + + countMap, err := countFunc(ctx, &Raven_IQ_test_visitproto.OpCountReq{ CtLowerBound: req.CtLowerBound, CtUpperBound: req.CtUpperBound, }) if err != nil { - logger.Error("OpCreate fail, req: %v, err: %v", util.ToJson(req), err) + logger.Error("countFunc fail, req: %v, err: %v", util.ToJson(req), err) ec = errcode.ErrCodeRavenIQTestVisitSrvFail return } diff --git a/app/mix/service/logic/Raven_IQ_test_visit.go b/app/mix/service/logic/Raven_IQ_test_visit.go index 16c00642..1b868d33 100644 --- a/app/mix/service/logic/Raven_IQ_test_visit.go +++ b/app/mix/service/logic/Raven_IQ_test_visit.go @@ -1,6 +1,7 @@ package logic import ( + "fmt" "service/api/consts" Raven_IQ_test_visitproto "service/api/proto/Raven_IQ_test_visit/proto" "service/app/mix/dao" @@ -42,11 +43,42 @@ func (p *RavenIQTestVisit) OpDelete(ctx *gin.Context, id int64) error { return nil } -func (p *RavenIQTestVisit) OpCount(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (int64, error) { - count, err := p.store.GetRavenIQTestVisitCount(ctx, req) +func (p *RavenIQTestVisit) OpCountPV(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (map[int64]int64, error) { + countMap := make(map[int64]int64) + mapList, err := p.store.GetRavenIQTestVisitPV(ctx, req) if err != nil { logger.Error("GetRavenIQTestVisitCount fail, err: %v", err) - return 0, err + return make(map[int64]int64), err } - return count, err + for _, _map := range mapList { + id, ok1 := _map["_id"].(int64) + pv, ok2 := _map["pv"].(int32) + if ok1 && ok2 { + countMap[id] = int64(pv) + } else { + logger.Error("assertion err") + return nil, fmt.Errorf("assertion err") + } + } + return countMap, err +} + +func (p *RavenIQTestVisit) OpCountUV(ctx *gin.Context, req *Raven_IQ_test_visitproto.OpCountReq) (map[int64]int64, error) { + countMap := make(map[int64]int64) + mapList, err := p.store.GetRavenIQTestVisitUV(ctx, req) + if err != nil { + logger.Error("GetRavenIQTestVisitCount fail, err: %v", err) + return make(map[int64]int64), err + } + for _, _map := range mapList { + id, ok1 := _map["_id"].(int64) + uv, ok2 := _map["uv"].(int32) + if ok1 && ok2 { + countMap[id] = int64(uv) + } else { + logger.Error("assertion err") + return nil, fmt.Errorf("assertion err") + } + } + return countMap, err }