Merge remote-tracking branch 'origin/feat-IRONFANS-173-Robin' into mainconflict

This commit is contained in:
Leufolium 2024-07-31 22:14:57 +08:00
commit 2793aff71d
26 changed files with 819 additions and 9 deletions

View File

@ -58,6 +58,11 @@ const (
StreamerScoreFormulaKey = "streamer_score_formula"
HvyogoSingleDistributeChargePercentageKey = "hvyogo_single_distribute_charge_percentage"
AutoResponseKey = "auto_response"
QuestionMapKey = "question_map"
AgeScore2IQResultMapKey = "age_score_2_IQ_result_map"
ClassScore2ClassResultMapKey = "class_score_2_class_result_map"
IQResultMapKey = "IQ_result_map"
ClassResultMapKey = "class_result_map"
)
// del_flag

View File

@ -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
)

View File

@ -10,6 +10,7 @@ var ErrCodeMsgMap = map[ErrCode]string{
ErrCodeApolloReadFail: "Apollo配置读取失败请立即联系管理员",
ErrCodeApolloVersionFormatError: "Apollo版本号配置格式错误",
ErrCodeUserVersionFormatError: "用户上送版本号格式错误",
ErrCodeIndexOutOfRange: "数组越界",
ErrCodeAssertionFail: "严重错误:类型断言异常,请立即联系管理员",
ErrCodeSelfOnlyOperation: "权限不足:该操作仅可对当前登录用户执行",
ErrCodeRolePrivilegesNotEnough: "权限不足:当前用户角色禁止执行该操作",
@ -241,6 +242,10 @@ var ErrCodeMsgMap = map[ErrCode]string{
ErrCodeVideoModerationSrvFail: "视频审核服务错误",
ErrCodeVideoModerationNotExist: "视频审核不存在",
ErrCodeRavenIQTestSrvFail: "瑞文智商测试表服务错误",
ErrCodeRavenIQTestNotExist: "瑞文智商测试表不存在",
ErrCodeRavenIQTestQuestionNotExist: "瑞文智商测试表题目不存在",
}
const (
@ -253,6 +258,7 @@ const (
ErrCodeAssertionFail ErrCode = -12 // 类型断言异常
ErrCodeApolloVersionFormatError ErrCode = -13 // Apollo版本号配置格式错误
ErrCodeUserVersionFormatError ErrCode = -14 // 用户上送版本号格式错误
ErrCodeIndexOutOfRange ErrCode = -15 // 数组越界
ErrCodeSelfOnlyOperation ErrCode = -20 // 权限不足:该操作仅可对当前登录用户执行
ErrCodeRolePrivilegesNotEnough ErrCode = -21 // 权限不足: 当前用户角色禁止执行该操作
ErrCodeOpRoleOnlyOperation ErrCode = -22 // 权限不足: 后台系统仅允许超级管理员和运营操作
@ -586,4 +592,9 @@ const (
// Websocket: 1xxxxx
ErrCodeHandleWsFail ErrCode = -100001 // 长链连接失败
// RavenIQTest: 101xxx
ErrCodeRavenIQTestSrvOk ErrCode = ErrCodeOk
ErrCodeRavenIQTestSrvFail ErrCode = -101001 // 瑞文智商测试表服务错误
ErrCodeRavenIQTestNotExist ErrCode = -101002 // 瑞文智商测试表不存在
ErrCodeRavenIQTestQuestionNotExist ErrCode = -101003 // 瑞文智商测试表题目不存在
)

View File

@ -0,0 +1,36 @@
package proto
import (
"service/api/base"
"service/dbstruct"
)
// op 创建
type ApiCreateReq struct {
base.BaseRequest
*dbstruct.RavenIQTest
}
type ApiCreateData struct {
Id int64 `json:"id"`
}
type ApiCreateResp struct {
base.BaseResponse
Data *ApiCreateData `json:"data"`
}
// op 列表
type ApiListReq struct {
base.BaseRequest
Id *int64 `json:"id"`
}
type ApiListData struct {
*ApiListVO
}
type ApiListResp struct {
base.BaseResponse
Data *ApiListData `json:"data"`
}

View File

@ -0,0 +1,66 @@
package proto
import (
"service/api/base"
"service/dbstruct"
)
// op 创建
type OpCreateReq struct {
base.BaseRequest
*dbstruct.RavenIQTest
}
type OpCreateData struct {
}
type OpCreateResp struct {
base.BaseResponse
Data *OpCreateData `json:"data"`
}
// op 删除
type OpDeleteReq struct {
base.BaseRequest
Id int64 `json:"id"`
}
type OpDeleteData struct {
}
type OpDeleteResp struct {
base.BaseResponse
Data *OpDeleteData `json:"data"`
}
// op 更新
type OpUpdateReq struct {
base.BaseRequest
*dbstruct.RavenIQTest
}
type OpUpdateData struct {
}
type OpUpdateResp struct {
base.BaseResponse
Data *OpUpdateData `json:"data"`
}
// op 列表
type OpListReq struct {
base.BaseRequest
Offset int `json:"offset"`
Limit int `json:"limit"`
}
type OpListData struct {
List []*dbstruct.RavenIQTest `json:"list"`
Offset int `json:"offset"`
More int `json:"more"`
}
type OpListResp struct {
base.BaseResponse
Data *OpListData `json:"data"`
}

View File

@ -0,0 +1,47 @@
package proto
import (
"service/apollostruct"
"service/dbstruct"
)
type ApiListVO struct {
Id int64 `json:"id"` // 瑞文智商测试表id
UserId string `json:"user_id"` // 用户id
Age int64 `json:"age"` // 年龄
TotalScore float64 `json:"total_score"` // 总得分
IQ int64 `json:"IQ"` // 智商值
*apollostruct.IQResult
ClassScoreList []*ApiClassScoreVO `json:"class_score_list"` // 大类得分list
}
type ApiClassScoreVO struct {
ClassBlockId int64 `json:"class_block_id"` // 大类得分key
Score int64 `json:"score"` // 总分
*apollostruct.ClassInfo
*apollostruct.ClassResult
}
func (vo *ApiListVO) CopyRavenIQTest(test *dbstruct.RavenIQTest) *ApiListVO {
if test == nil {
return vo
}
vo.IQResult = &apollostruct.IQResult{}
vo.Id = test.GetId()
vo.UserId = test.GetUserId()
vo.Age = test.GetAge()
vo.TotalScore = test.GetTotalScore()
vo.IQ = test.GetIQ()
vo.IQBlockId = test.GetIQBlockId()
vo.ClassScoreList = make([]*ApiClassScoreVO, 0)
for _, score := range test.ClassScoreList {
vo.ClassScoreList = append(vo.ClassScoreList, &ApiClassScoreVO{
ClassBlockId: score.GetClassBlockId(),
Score: score.GetConvertedScore(),
ClassInfo: &apollostruct.ClassInfo{
ClassId: score.GetClassId(),
},
})
}
return vo
}

View File

@ -0,0 +1,20 @@
package proto
import (
"service/library/validator"
)
// api 查询
func (p *ApiCreateReq) ProvideNotNullValue() (params []*validator.JsonParam) {
params = make([]*validator.JsonParam, 0)
params = append(params, validator.NewInt64PtrParam("请提供您的年龄!", p.Age))
params = append(params, validator.NewStructSliceParam("请提供您的答案!", len(p.RavenIQTest.AnswerList)))
return params
}
// api 经验增长
func (p *ApiListReq) ProvideNotNullValue() (params []*validator.JsonParam) {
params = make([]*validator.JsonParam, 0)
params = append(params, validator.NewInt64PtrParam("请提供待查询的id", p.Id))
return params
}

View File

@ -0,0 +1,65 @@
package apollostruct
type QuestionMapCfg struct {
Map map[int64]*RavenIQTestQuestion `json:"map"`
ClassList []int64 `json:"class_list"`
}
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
IQGrade string `json:"IQ_grade"` // 智商等级
Percentile int64 `json:"percentile"` // 百分位
IQLowerBound int64 `json:"IQ_lower_bound"` // IQ下界
IQUpperBound int64 `json:"IQ_upper_bound"` // IQ上界
Description string `json:"description"` // 描述
Suggestions []string `json:"suggestions"` // 建议
}
type AgeScore2IQResultMapCfg struct {
AgeBlockIndex2ScoreBlockListMap map[int][]float64 `json:"age_block_index_2_score_block_list_map"` // 年龄分段到分数分布区域的映射map
AgeBlockList []int64 `json:"age_block_list"` // 年龄段区域,以年龄在该年龄段中第一次出现或最后一个比他小的位置作为年龄段索引
ScoreBlockIndex2IQBlockIdMap map[int]int64 `json:"score_block_index_2_IQ_block_id_map"` // 分数分段到IQ范围id的映射map
}
type ClassScore2ClassResultMapCfg struct {
Map map[int64][]int64 `json:"map" bson:"map"` // 大类Id到大类分数分布区域的映射map
}
type IQResultMapCfg struct {
Map map[int64]*IQResult `json:"map"`
}
type ClassResult struct {
Description string `json:"description"` // 描述
Analysis string `json:"analysis"` // 成绩分析
Suggestions []*Suggestion `json:"suggestions"` // 建议
}
type ClassInfo struct {
ClassId int64 `json:"class_id"` // 大类id
ClassName string `json:"class_name"` // 大类名称
ClassFullScore int64 `json:"class_full_score"` // 大类满分
}
type Suggestion struct {
Title string `json:"title"`
Tips []*Tip `json:"tips"`
}
type Tip struct {
Summary string `json:"summary"` // 概括
Content string `json:"content"` // 内容
}
type ClassResultMapCfg struct {
Map map[int64]*ClassResult `json:"map"`
ClassInfoMap map[int64]*ClassInfo `json:"class_info_map"`
FullScore int64 `json:"full_score"` // 满分
TotalScore int64 `json:"total_score"` // 总分
}

View File

@ -0,0 +1,42 @@
package controller
import (
"service/api/errcode"
Raven_IQ_testproto "service/api/proto/Raven_IQ_test/proto"
"service/app/mix/service"
"service/bizcommon/util"
"service/library/logger"
"github.com/gin-gonic/gin"
)
func ApiCreateRavenIQTest(ctx *gin.Context) {
req := ctx.MustGet("client_req").(*Raven_IQ_testproto.ApiCreateReq)
id, ec := service.DefaultService.ApiCreateRavenIQTest(ctx, req)
if ec != errcode.ErrCodeRavenIQTestSrvOk {
logger.Error("ApiCreateRavenIQTest fail, req: %v, ec: %v", util.ToJson(req), ec)
ReplyErrorMsg(ctx, "server error")
return
}
data := &Raven_IQ_testproto.ApiCreateData{
Id: id,
}
ReplyOk(ctx, data)
}
func ApiGetRavenIQTestList(ctx *gin.Context) {
req := ctx.MustGet("client_req").(*Raven_IQ_testproto.ApiListReq)
vo, ec := service.DefaultService.ApiGetRavenIQTestList(ctx, req)
if ec != errcode.ErrCodeRavenIQTestSrvOk {
logger.Error("ApiGetRavenIQTestList fail, req: %v, ec: %v", util.ToJson(req), ec)
ReplyErrCodeMsg(ctx, ec)
return
}
data := &Raven_IQ_testproto.ApiListData{
ApiListVO: vo,
}
ReplyOk(ctx, data)
}

View File

@ -19,6 +19,7 @@ import (
"service/api/base"
"service/api/consts"
"service/api/errcode"
Raven_IQ_testproto "service/api/proto/Raven_IQ_test/proto"
accountproto "service/api/proto/account/proto"
account_cancellationproto "service/api/proto/account_cancellation/proto"
accountpunishmentproto "service/api/proto/accountpunishment/proto"
@ -286,6 +287,11 @@ func Init(r *gin.Engine) {
apiHvyogoGroup.POST("single_distribute", middleware.JSONParamValidator(hvyogoproto.ApiSingleDistributeReq{}), middleware.JwtAuthenticator(), middleware.RequestDecryptor(), ApiHvyogoSingleDistribute)
apiHvyogoGroup.POST("worker_update", middleware.JSONParamValidator(hvyogoproto.ApiWorkerUpdateReq{}), middleware.JwtAuthenticator(), middleware.RequestDecryptor(), ApiHvyogoWorkerUpdate)
// 瑞文智商测试表
apiRavenIQTestGroup := r.Group("/api/Raven_IQ_test", PrepareToC())
apiRavenIQTestGroup.POST("create", middleware.JSONParamValidator(Raven_IQ_testproto.ApiCreateReq{}), ApiCreateRavenIQTest)
apiRavenIQTestGroup.POST("list", middleware.JSONParamValidator(Raven_IQ_testproto.ApiListReq{}), ApiGetRavenIQTestList)
// =============================== 以下是服务,只允许内网调用 ===============================
// op相关直接调用服务不调用gateway

View File

@ -17,6 +17,7 @@ import (
"go.mongodb.org/mongo-driver/bson"
options2 "go.mongodb.org/mongo-driver/mongo/options"
Raven_IQ_testproto "service/api/proto/Raven_IQ_test/proto"
accountproto "service/api/proto/account/proto"
account_cancellationproto "service/api/proto/account_cancellation/proto"
accountpunishmentproto "service/api/proto/accountpunishment/proto"
@ -235,6 +236,9 @@ const (
DBSingleDistributeHis = "single_distribute_his"
COLSingleDistributeHis = "single_distribute_his"
COLSingleDistributeLock = "single_distribute_lock"
DBRavenIQTest = "Raven_IQ_test"
COLRavenIQTest = "Raven_IQ_test"
)
// 商品表
@ -611,6 +615,11 @@ func (m *Mongo) getColSingleDistributeLock() *qmgo.Collection {
return m.clientMix.Database(DBSingleDistributeHis).Collection(COLSingleDistributeLock)
}
// 瑞文智商测试表表
func (m *Mongo) getColRavenIQTest() *qmgo.Collection {
return m.clientMix.Database(DBRavenIQTest).Collection(COLRavenIQTest)
}
// 商品相关
func (m *Mongo) CreateProduct(ctx *gin.Context, product *dbstruct.Product) error {
col := m.getColProduct()
@ -6021,3 +6030,61 @@ func (m *Mongo) GetSingleDistributeHisById(ctx *gin.Context, id string) (*dbstru
}
return one, err
}
// 瑞文智商测试表相关
func (m *Mongo) CreateRavenIQTest(ctx *gin.Context, Raven_IQ_test *dbstruct.RavenIQTest) error {
col := m.getColRavenIQTest()
_, err := col.InsertOne(ctx, Raven_IQ_test)
return err
}
func (m *Mongo) UpdateRavenIQTest(ctx *gin.Context, Raven_IQ_test *dbstruct.RavenIQTest) error {
col := m.getColRavenIQTest()
set := util.EntityToM(Raven_IQ_test)
set["ut"] = time.Now().Unix()
up := qmgo.M{
"$set": set,
}
err := col.UpdateId(ctx, Raven_IQ_test.Id, up)
return err
}
func (m *Mongo) DeleteRavenIQTest(ctx *gin.Context, id int64) error {
col := m.getColRavenIQTest()
update := qmgo.M{
"$set": qmgo.M{
"del_flag": 1,
},
}
err := col.UpdateId(ctx, id, update)
return err
}
func (m *Mongo) GetRavenIQTestList(ctx *gin.Context, req *Raven_IQ_testproto.OpListReq) ([]*dbstruct.RavenIQTest, error) {
list := make([]*dbstruct.RavenIQTest, 0)
col := m.getColRavenIQTest()
query := qmgo.M{
"del_flag": 0,
}
err := col.Find(ctx, query).Sort("-ct").Skip(int64(req.Offset)).Limit(int64(req.Limit)).All(&list)
if err == qmgo.ErrNoSuchDocuments {
err = nil
return list, err
}
return list, err
}
func (m *Mongo) GetRavenIQTestById(ctx *gin.Context, id int64) (*dbstruct.RavenIQTest, error) {
test := &dbstruct.RavenIQTest{}
col := m.getColRavenIQTest()
query := qmgo.M{
"_id": id,
"del_flag": 0,
}
err := col.Find(ctx, query).One(test)
if err == qmgo.ErrNoSuchDocuments {
err = nil
return nil, err
}
return test, err
}

View File

@ -64,6 +64,9 @@ const (
COLImageAuditRTI = "image_audit_rti"
COLTextAuditRTI = "text_audit_rti"
COLVideoModerationRTI = "video_moderation_rti"
DBRavenIQTestIdSeq = "Raven_IQ_test_id_seq"
COLRavenIQTestIdSeq = "Raven_IQ_test_id_seq"
)
// UserIdSeq序列表
@ -171,6 +174,11 @@ func (m *Mongo) getColVideoModerationRTI() *qmgo.Collection {
return m.clientMix.Database(DBContentAuditRTI).Collection(COLVideoModerationRTI)
}
// AccountIdSeq序列表
func (m *Mongo) getColRavenIQTestIdSeq() *qmgo.Collection {
return m.clientMix.Database(DBRavenIQTestIdSeq).Collection(COLRavenIQTestIdSeq)
}
// account_id发号器
func (m *Mongo) GetAndUpdateAccountIdSeq(ctx *gin.Context) (accountIdSeq *dbstruct.AccountIdSeq, err error) {
col := m.getColAccountIdSeq()
@ -619,3 +627,22 @@ func (m *Mongo) GetVideoModerationBatchId(ctx *gin.Context) (videoModerationBatc
return
}
// Raven_IQ_test_id发号器
func (m *Mongo) GetAndUpdateRavenIQTestIdSeq(ctx *gin.Context) (Raven_IQ_testIdSeq *dbstruct.RavenIQTestIdSeq, err error) {
col := m.getColRavenIQTestIdSeq()
change := qmgo.Change{
Update: qmgo.M{"$inc": qmgo.M{"seq": 1}},
Upsert: true,
ReturnNew: false,
}
instance := dbstruct.RavenIQTestIdSeq{}
if err = col.Find(ctx, qmgo.M{"_id": "Raven_IQ_test_id_seq_id"}).Apply(change, &instance); err != nil {
logger.Error("change error : %v", err)
return
}
return &instance, err
}

View File

@ -2,6 +2,7 @@ package service
import (
"fmt"
"math"
"service/api/base"
"service/api/consts"
"service/api/errcode"
@ -53,6 +54,8 @@ import (
"strings"
"time"
Raven_IQ_testproto "service/api/proto/Raven_IQ_test/proto"
"go.mongodb.org/mongo-driver/mongo"
goproto "google.golang.org/protobuf/proto"
@ -3987,3 +3990,139 @@ func (s *Service) ApiHvyogoWorkerUpdate(ctx *gin.Context, req *hvyogoproto.ApiWo
return
}
// RavenIQTest
func (s *Service) ApiCreateRavenIQTest(ctx *gin.Context, req *Raven_IQ_testproto.ApiCreateReq) (id int64, ec errcode.ErrCode) {
ec = errcode.ErrCodeRavenIQTestSrvOk
// 缓存数据准备
questionMapcfg := apollostruct.QuestionMapCfg{}
ageScore2IQResultMapCfg := apollostruct.AgeScore2IQResultMapCfg{}
classScore2ClassResultMapCfg := apollostruct.ClassScore2ClassResultMapCfg{}
IQResultMpcfg := apollostruct.IQResultMapCfg{}
classResultMpCfg := apollostruct.ClassResultMapCfg{}
keys := []string{consts.QuestionMapKey, consts.AgeScore2IQResultMapKey, consts.ClassScore2ClassResultMapKey, consts.IQResultMapKey, consts.ClassResultMapKey}
cfgs := []any{&questionMapcfg, &ageScore2IQResultMapCfg, &classScore2ClassResultMapCfg, &IQResultMpcfg, &classResultMpCfg}
err := apollo.GetJsons(keys, cfgs, apollo.ApolloOpts().SetNamespace("Raven_IQ_test"))
if err != nil {
logger.Error("Apollo read failed : %v", err)
return -1, errcode.ErrCodeApolloReadFail
}
// 计算大类得分、总得分情况
classScoreMap := make(map[int64]int64)
for _, classId := range questionMapcfg.ClassList {
classScoreMap[classId] = 0
}
for _, answer := range req.AnswerList {
question, ok := questionMapcfg.Map[answer.GetQuestionId()]
if !ok {
return -1, errcode.ErrCodeRavenIQTestQuestionNotExist
}
if answer.GetSelectedOption() == question.CorrectOption {
classScoreMap[question.ClassId] += 1
}
}
req.ClassScoreList = make([]*dbstruct.RavenIQTestClassScore, 0)
totalScore := float64(0)
for classId, score := range classScoreMap {
classInfo := classResultMpCfg.ClassInfoMap[classId]
covertedScore := int64(math.Ceil(((float64(score) / float64(classResultMpCfg.TotalScore) * float64(classResultMpCfg.FullScore)) + float64(classInfo.ClassFullScore)) / 2))
req.ClassScoreList = append(req.ClassScoreList, &dbstruct.RavenIQTestClassScore{
ClassId: goproto.Int64(classId),
Score: goproto.Int64(score),
ConvertedScore: goproto.Int64(covertedScore),
})
totalScore += float64(score)
}
req.TotalScore = goproto.Float64(totalScore)
// 获取IQ分组id
ageBlockIdx := util.GetLastLessOrEqualForInt64(ageScore2IQResultMapCfg.AgeBlockList, req.GetAge())
list := ageScore2IQResultMapCfg.AgeBlockIndex2ScoreBlockListMap[ageBlockIdx]
scoreBlockIdx := util.GetLastLessOrEqualForFloat64(list, req.GetTotalScore())
if scoreBlockIdx == -1 || scoreBlockIdx >= len(list)-1 {
logger.Error("array index out of bound...")
return -1, errcode.ErrCodeIndexOutOfRange
}
IQBlockId := ageScore2IQResultMapCfg.ScoreBlockIndex2IQBlockIdMap[scoreBlockIdx]
for _, classScore := range req.ClassScoreList {
classScoreBlockList := classScore2ClassResultMapCfg.Map[classScore.GetClassId()]
classScoreBlockIdx := util.GetLastLessOrEqualForInt64(classScoreBlockList, classScore.GetScore())
classScore.ClassBlockId = goproto.Int64(classScore.GetClassId()*100 + int64(classScoreBlockIdx)) // 100 * 大类id + 偏移量
}
req.IQBlockId = goproto.Int64(IQBlockId)
// 计算智商
totalScoreLowerBound := list[scoreBlockIdx]
totalScoreUpperBound := list[scoreBlockIdx+1] - 1
IQLowerBound := float64(IQResultMpcfg.Map[IQBlockId].IQLowerBound)
IQUpperBound := float64(IQResultMpcfg.Map[IQBlockId].IQUpperBound)
IQ := int64(math.Ceil(float64(totalScore-totalScoreLowerBound)/float64(totalScoreUpperBound-totalScoreLowerBound)*(IQUpperBound-IQLowerBound) + IQLowerBound))
if IQ < 70 {
IQ = 70
}
req.IQ = goproto.Int64(IQ)
err = _DefaultRavenIQTest.OpCreate(ctx, &Raven_IQ_testproto.OpCreateReq{
BaseRequest: req.BaseRequest,
RavenIQTest: req.RavenIQTest,
})
if err != nil {
logger.Error("ApiCreate fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeRavenIQTestSrvFail
return
}
id = req.RavenIQTest.GetId()
return
}
func (s *Service) ApiGetRavenIQTestList(ctx *gin.Context, req *Raven_IQ_testproto.ApiListReq) (vo *Raven_IQ_testproto.ApiListVO, ec errcode.ErrCode) {
ec = errcode.ErrCodeRavenIQTestSrvOk
vo = &Raven_IQ_testproto.ApiListVO{}
test, err := _DefaultRavenIQTest.GetById(ctx, util.DerefInt64(req.Id))
if err != nil {
logger.Error("ApiGetRavenIQTest fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeRavenIQTestSrvFail
return
}
if test == nil {
logger.Error("No RavenIQTest entity was found, req: %v", util.ToJson(req))
ec = errcode.ErrCodeRavenIQTestNotExist
return
}
vo.CopyRavenIQTest(test)
// 填充业务数据
IQResultMpcfg := apollostruct.IQResultMapCfg{}
err = apollo.GetJson(consts.IQResultMapKey, &IQResultMpcfg, apollo.ApolloOpts().SetNamespace("Raven_IQ_test"))
if err != nil {
logger.Error("Apollo read failed : %v", err)
ec = errcode.ErrCodeApolloReadFail
return
}
classResultMpCfg := apollostruct.ClassResultMapCfg{}
err = apollo.GetJson(consts.ClassResultMapKey, &classResultMpCfg, apollo.ApolloOpts().SetNamespace("Raven_IQ_test"))
if err != nil {
logger.Error("Apollo read failed : %v", err)
ec = errcode.ErrCodeApolloReadFail
return
}
vo.IQResult = IQResultMpcfg.Map[vo.IQBlockId]
for _, classScore := range vo.ClassScoreList {
classScore.ClassResult = classResultMpCfg.Map[classScore.ClassBlockId]
classScore.ClassInfo = classResultMpCfg.ClassInfoMap[classScore.ClassInfo.ClassId]
}
return
}

View File

@ -0,0 +1,81 @@
package logic
import (
"service/api/consts"
Raven_IQ_testproto "service/api/proto/Raven_IQ_test/proto"
"service/app/mix/dao"
"service/dbstruct"
"service/library/logger"
"time"
"github.com/gin-gonic/gin"
goproto "google.golang.org/protobuf/proto"
)
type RavenIQTest struct {
store *dao.Store
}
func NewRavenIQTest(store *dao.Store) (a *RavenIQTest) {
a = &RavenIQTest{
store: store,
}
return
}
func (p *RavenIQTest) OpCreate(ctx *gin.Context, req *Raven_IQ_testproto.OpCreateReq) error {
//产生mid
idSeq, err := p.store.GetAndUpdateRavenIQTestIdSeq(ctx)
if err != nil {
logger.Error("GetAndUpdateRavenIQTestIdSeq failed : %v", err)
return err
}
req.RavenIQTest.Id = goproto.Int64(idSeq.Seq)
req.RavenIQTest.Ct = goproto.Int64(time.Now().Unix())
req.RavenIQTest.Ut = goproto.Int64(time.Now().Unix())
req.RavenIQTest.DelFlag = goproto.Int64(consts.Exist)
err = p.store.CreateRavenIQTest(ctx, req.RavenIQTest)
if err != nil {
logger.Error("CreateRavenIQTest fail, err: %v", err)
return err
}
return nil
}
func (p *RavenIQTest) OpUpdate(ctx *gin.Context, req *Raven_IQ_testproto.OpUpdateReq) error {
err := p.store.UpdateRavenIQTest(ctx, req.RavenIQTest)
if err != nil {
logger.Error("UpdateRavenIQTest fail, err: %v", err)
return err
}
return nil
}
func (p *RavenIQTest) OpDelete(ctx *gin.Context, id int64) error {
err := p.store.DeleteRavenIQTest(ctx, id)
if err != nil {
logger.Error("DeleteRavenIQTest fail, err: %v", err)
return err
}
return nil
}
func (p *RavenIQTest) OpList(ctx *gin.Context, req *Raven_IQ_testproto.OpListReq) ([]*dbstruct.RavenIQTest, error) {
list, err := p.store.GetRavenIQTestList(ctx, req)
if err != nil {
logger.Error("GetRavenIQTestList fail, err: %v", err)
return make([]*dbstruct.RavenIQTest, 0), err
}
return list, nil
}
func (p *RavenIQTest) GetById(ctx *gin.Context, id int64) (*dbstruct.RavenIQTest, error) {
test, err := p.store.GetRavenIQTestById(ctx, id)
if err != nil {
logger.Error("GetRavenIQTestListByIds fail, id: %v, err: %v", id, err)
return nil, err
}
return test, nil
}

View File

@ -150,6 +150,7 @@ var (
_DefaultWorkerId *logic.WorkerId
_DefaultSingleDistributeHis *logic.SingleDistributeHis
_DefaultAutoResponseCreateTimes *logic.AutoResponseCreateTimes
_DefaultRavenIQTest *logic.RavenIQTest
)
type Service struct {
@ -250,6 +251,7 @@ func (s *Service) Init(c any) (err error) {
_DefaultWorkerId = logic.NewWorkerId(store)
_DefaultSingleDistributeHis = logic.NewSingleDistributeHis(store)
_DefaultAutoResponseCreateTimes = logic.NewAutoResponseCreateTimes(store)
_DefaultRavenIQTest = logic.NewRavenIQTest(store)
_DefaultVas = logic.NewVas(store, _DefaultStreamer, _DefaultAccount, _DefaultZone, _DefaultZoneThirdPartner, _DefaultZoneCollaborator)
_DefaultStreamerAcct = logic.NewStreamerAcct(store)

View File

@ -337,3 +337,39 @@ func IsInt64SliceEqualAsSet(s1 []int64, s2 []int64) bool {
}
return true
}
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
}

View File

@ -9,10 +9,10 @@ import (
func main() {
genSource := &generator.GenSource{
EntityName: "SingleDistributeHis",
ModuleName: "single_distribute_his",
EntityCNName: "慧用工下发打款历史表",
ErrCodeSeq: "42",
EntityName: "RavenIQTest",
ModuleName: "Raven_IQ_test",
EntityCNName: "瑞文智商测试表",
ErrCodeSeq: "101",
}
generator.CreateFileDirectory(genSource)

111
dbstruct/RavenIQTest.go Normal file
View File

@ -0,0 +1,111 @@
package dbstruct
type RavenIQTest struct {
Id *int64 `json:"id" bson:"_id"` // 瑞文智商测试表id
UserId *string `json:"user_id" bson:"user_id"` // 用户id
Age *int64 `json:"age" bson:"age"` // 年龄
TotalScore *float64 `json:"total_score" bson:"total_score"` // 总得分
IQBlockId *int64 `json:"IQ_block_id" bson:"IQ_block_id"` // 智商值key
IQ *int64 `json:"IQ" bson:"IQ"` // 智商值
AnswerList []*RavenIQTestAnswer `json:"answer_list" bson:"answer_list"` // 答案list
ClassScoreList []*RavenIQTestClassScore `json:"class_score_list" bson:"class_score_list"` // 大类得分list
Ct *int64 `json:"ct" bson:"ct"` // 创建时间
Ut *int64 `json:"ut" bson:"ut"` // 更新时间
DelFlag *int64 `json:"del_flag" bson:"del_flag"` // 删除标记
}
type RavenIQTestAnswer struct {
QuestionId *int64 `json:"question_id" bson:"question_id"` // 问题Id
SelectedOption *int64 `json:"selected_option" bson:"selected_option"` // 选择的选项
}
type RavenIQTestClassScore struct {
ClassId *int64 `json:"class_id" bson:"class_id"` // 大类id
Score *int64 `json:"score" bson:"score"` // 得分
ClassBlockId *int64 `json:"class_block_id" bson:"class_block_id"` // 大类得分key
ConvertedScore *int64 `json:"converted_score" bson:"converted_score"` // 折算后得分
}
func (p *RavenIQTest) GetId() int64 {
if p == nil || p.Id == nil {
return -1
}
return *p.Id
}
func (p *RavenIQTest) GetUserId() string {
if p == nil || p.UserId == nil {
return ""
}
return *p.UserId
}
func (p *RavenIQTest) GetAge() int64 {
if p == nil || p.Age == nil {
return 0
}
return *p.Age
}
func (p *RavenIQTest) GetTotalScore() float64 {
if p == nil || p.TotalScore == nil {
return 0
}
return *p.TotalScore
}
func (p *RavenIQTest) GetIQBlockId() int64 {
if p == nil || p.IQBlockId == nil {
return 0
}
return *p.IQBlockId
}
func (p *RavenIQTest) GetIQ() int64 {
if p == nil || p.IQ == nil {
return 0
}
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
}
return *p.ClassId
}
func (p *RavenIQTestClassScore) GetScore() int64 {
if p == nil || p.Score == nil {
return 0
}
return *p.Score
}
func (p *RavenIQTestClassScore) GetConvertedScore() int64 {
if p == nil || p.ConvertedScore == nil {
return 0
}
return *p.ConvertedScore
}
func (p *RavenIQTestClassScore) GetClassBlockId() int64 {
if p == nil || p.ClassBlockId == nil {
return 0
}
return *p.ClassBlockId
}

View File

@ -88,3 +88,7 @@ type TextAuditBatchId struct {
type VideoModerationBatchId struct {
BatchId string `json:"batch_id" bson:"batch_id"` //视频审核批次号
}
type RavenIQTestIdSeq struct {
Seq int64 //用户Id序列号
}

View File

@ -85,7 +85,7 @@ apollo:
app_id: "wishpal_live_service"
cluster: "dev"
ip: "http://localhost:8080"
namespace_name: "application,tag,account_init,platform,support_wx_id"
namespace_name: "application,tag,account_init,platform,support_wx_id,Raven_IQ_test"
secret: ""
is_back_up_config: true
sync_server_timeout: 2

View File

@ -95,7 +95,7 @@ apollo:
app_id: "wishpal_live_service"
cluster: "dev"
ip: "http://172.16.0.186:8080"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone,Raven_IQ_test"
secret: ""
is_back_up_config: true
sync_server_timeout: 2

View File

@ -95,7 +95,7 @@ apollo:
app_id: "wishpal_live_service"
cluster: "dev"
ip: "http://172.16.0.186:8080"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone,Raven_IQ_test"
secret: ""
is_back_up_config: true
sync_server_timeout: 2

View File

@ -97,7 +97,7 @@ apollo:
app_id: "wishpal_live_service"
cluster: "dev"
ip: "http://localhost:8080"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone,Raven_IQ_test"
secret: ""
is_back_up_config: true
sync_server_timeout: 2

View File

@ -96,7 +96,7 @@ apollo:
app_id: "wishpal_live_service"
cluster: "dev"
ip: "http://172.31.37.71:8080"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone"
namespace_name: "application,tag,account_init,platform,support_wx_id,version,zone,Raven_IQ_test"
secret: ""
is_back_up_config: true
sync_server_timeout: 2

View File

@ -147,3 +147,23 @@ func GetFloat64Value(key string, opts ...*ApolloOptions) (value float64, err err
}
return
}
func GetJsons(keys []string, vs []interface{}, opts ...*ApolloOptions) (err error) {
opt := mergeApolloOptions(opts...)
for i, key := range keys {
var value string
if opt.GetNamespace() != "" {
value = defaultApolloClient.GetConfig(opt.GetNamespace()).GetStringValue(key, opt.GetDefaultValue())
} else {
value = defaultApolloClient.GetStringValue(key, opt.GetDefaultValue())
}
if value != "" {
err = json.Unmarshal([]byte(value), vs[i])
if err != nil {
return
}
}
}
return
}