diff --git a/api/consts/consts.go b/api/consts/consts.go index 04fe0472..3c9f4f5f 100644 --- a/api/consts/consts.go +++ b/api/consts/consts.go @@ -57,6 +57,8 @@ const ( ZoneVIPConfigKey = "zone_vip_config" StreamerScoreFormulaKey = "streamer_score_formula" HvyogoSingleDistributeChargePercentageKey = "hvyogo_single_distribute_charge_percentage" + QuestionMapKey = "question_map" + AgeScore2IQResultMap = "age_score_2_IQ_result_map" ) // del_flag diff --git a/api/consts/predicate.go b/api/consts/predicate.go index 58366d5c..380bc8c9 100644 --- a/api/consts/predicate.go +++ b/api/consts/predicate.go @@ -28,3 +28,28 @@ const ( ContactCustomerService_FromUser = 0 ContactCustomerService_FromSupportor = 1 ) + +// Raven_IQ_test 年龄段谓词 +const ( + Age1 = 1 + Age2 = 2 + Age3 = 3 + Age4 = 4 + Age5 = 5 + Age6 = 6 + Age7 = 7 + Age8 = 8 + Age9 = 9 + Age10 = 10 +) + +// Raven_IQ_test 智商段谓词 +const ( + IQSegment1 = 1 + IQSegment2 = 2 + IQSegment3 = 3 + IQSegment4 = 4 + IQSegment5 = 5 + IQSegment6 = 6 + IQSegment7 = 7 +) diff --git a/apollostruct/RavenIQtest.go b/apollostruct/RavenIQtest.go new file mode 100644 index 00000000..7afcec21 --- /dev/null +++ b/apollostruct/RavenIQtest.go @@ -0,0 +1,23 @@ +package apollostruct + +type QuestionMapCfg struct { + Map map[int64]*RavenIQTestQuestion `json:"map"` +} + +type RavenIQTestQuestion struct { + QuestionId int64 `json:"question_id" bson:"question_id"` // 问题Id + ClassId int64 `json:"class_id" bson:"class_id"` // 大类id + CorrectOption int64 `json:"correct_option" bson:"correct_option"` // 正确选项 +} + +type IQResult struct { + IQBlockId int64 `json:"IQ_Block_Id"` // IQ分段id + Percentile int64 `json:"percentile"` // 百分位 + Description string `json:"description"` // 描述 +} + +type AgeScore2IQResultMapCfg struct { + AgeBlockIndex2ScoreBlockListMap map[int][]float64 `json:"age_block_index_2_score_block_list_map"` // 年龄分段到分数分布区域的映射map + AgeBlockList []int64 `json:"age_block_list"` // 年龄段区域,以年龄在该年龄段中第一次出现或最后一个比他小的位置作为年龄段索引 + ScoreBlockIndex2IQResultMap map[int]*IQResult `json:"score_block_index_2_IQ_result_map"` // 分数分段到IQ结果的映射map +} diff --git a/app/mix/service/apiservice.go b/app/mix/service/apiservice.go index ceb03538..bb00cb53 100644 --- a/app/mix/service/apiservice.go +++ b/app/mix/service/apiservice.go @@ -3593,8 +3593,45 @@ func (s *Service) ApiCreateRavenIQTest(ctx *gin.Context, req *Raven_IQ_testproto ec = errcode.ErrCodeRavenIQTestSrvOk // 计算总得分 + questionMapcfg := apollostruct.QuestionMapCfg{} + err := apollo.GetJson(consts.QuestionMapKey, &questionMapcfg, apollo.ApolloOpts().SetNamespace("Raven_IQ_test")) + if err != nil { + logger.Error("Apollo read failed : %v", err) + return errcode.ErrCodeApolloReadFail + } - err := _DefaultRavenIQTest.OpCreate(ctx, &Raven_IQ_testproto.OpCreateReq{ + classScoreMap := make(map[int64]int64) + for _, answer := range req.AnswerList { + if answer.GetSelectedOption() == questionMapcfg.Map[answer.GetQuestionId()].CorrectOption { + classScoreMap[answer.GetQuestionId()] += 1 + } + } + + req.ClassScoreList = make([]*dbstruct.RavenIQTestClassScore, 0) + totalScore := float64(0) + for classId, score := range classScoreMap { + req.ClassScoreList = append(req.ClassScoreList, &dbstruct.RavenIQTestClassScore{ + ClassId: goproto.Int64(classId), + Score: goproto.Int64(score), + }) + totalScore += float64(score) + } + req.TotalScore = goproto.Float64(totalScore) + + // 换算智商及百分位 + cfg := apollostruct.AgeScore2IQResultMapCfg{} + err = apollo.GetJson(consts.AgeScore2IQResultMap, &cfg, apollo.ApolloOpts().SetNamespace("Raven_IQ_test")) + if err != nil { + logger.Error("Apollo read failed : %v", err) + ec = errcode.ErrCodeApolloReadFail + return + } + idx := util.GetLastLessOrEqualForInt64(cfg.AgeBlockList, req.GetAge()) + list := cfg.AgeBlockIndex2ScoreBlockListMap[idx] + idx2 := util.GetLastLessOrEqualForFloat64(list, req.GetTotalScore()) + IQResult := cfg.ScoreBlockIndex2IQResultMap[idx2] + + err = _DefaultRavenIQTest.OpCreate(ctx, &Raven_IQ_testproto.OpCreateReq{ BaseRequest: req.BaseRequest, RavenIQTest: req.RavenIQTest, }) diff --git a/bizcommon/util/util.go b/bizcommon/util/util.go index e08f3b6b..7e189fbd 100644 --- a/bizcommon/util/util.go +++ b/bizcommon/util/util.go @@ -217,3 +217,39 @@ func SortParam(argList []*message.JsonParamEntry) string { } return strings.Join(args, "&") } + +func GetLastLessOrEqualForInt64(arr []int64, target int64) int { + low, high := 0, len(arr)-1 + result := -1 + + for low <= high { + mid := (low + high) / 2 + + if arr[mid] <= target { + result = mid // 记录当前找到的索引 + low = mid + 1 // 继续在右半部分查找 + } else { + high = mid - 1 // 目标值在左半部分,缩小搜索范围 + } + } + + return result +} + +func GetLastLessOrEqualForFloat64(arr []float64, target float64) int { + low, high := 0, len(arr)-1 + result := -1 + + for low <= high { + mid := (low + high) / 2 + + if arr[mid] <= target { + result = mid // 记录当前找到的索引 + low = mid + 1 // 继续在右半部分查找 + } else { + high = mid - 1 // 目标值在左半部分,缩小搜索范围 + } + } + + return result +} diff --git a/dbstruct/RavenIQTest.go b/dbstruct/RavenIQTest.go index 5f42b80a..64efb754 100644 --- a/dbstruct/RavenIQTest.go +++ b/dbstruct/RavenIQTest.go @@ -4,7 +4,7 @@ type RavenIQTest struct { Id *int64 `json:"id" bson:"_id"` // 瑞文智商测试表id UserId *int64 `json:"user_id" bson:"user_id"` // 用户id Age *int64 `json:"age" bson:"age"` // 年龄 - TotalScores *int64 `json:"total_scores" bson:"total_scores"` // 总得分 + TotalScore *float64 `json:"total_score" bson:"total_score"` // 总得分 IQ *float64 `json:"IQ" bson:"IQ"` // 智商值 AnswerList []*RavenIQTestAnswer `json:"answer_list" bson:"answer_list"` // 答案list ClassScoreList []*RavenIQTestClassScore `json:"class_score_list" bson:"class_score_list"` // 大类得分list @@ -44,11 +44,11 @@ func (p *RavenIQTest) GetAge() int64 { return *p.Age } -func (p *RavenIQTest) GetTotalScores() int64 { - if p == nil || p.TotalScores == nil { +func (p *RavenIQTest) GetTotalScore() float64 { + if p == nil || p.TotalScore == nil { return 0 } - return *p.TotalScores + return *p.TotalScore } func (p *RavenIQTest) GetIQ() float64 { @@ -58,6 +58,20 @@ func (p *RavenIQTest) GetIQ() float64 { return *p.IQ } +func (p *RavenIQTestAnswer) GetQuestionId() int64 { + if p == nil || p.QuestionId == nil { + return 0 + } + return *p.QuestionId +} + +func (p *RavenIQTestAnswer) GetSelectedOption() int64 { + if p == nil || p.SelectedOption == nil { + return 0 + } + return *p.SelectedOption +} + func (p *RavenIQTestClassScore) GetClassId() int64 { if p == nil || p.ClassId == nil { return 0