diff --git a/api/dao/QuestionQaItem.go b/api/dao/QuestionQaItem.go index 80f7c46..6c4d0d0 100644 --- a/api/dao/QuestionQaItem.go +++ b/api/dao/QuestionQaItem.go @@ -91,6 +91,15 @@ func (r *QuestionQaItemDao) GetQuestionQaItemPreloadList(maps interface{}) (m [] return m, nil } +// GetQuestionQaItemPreloadListRand 获取列表-加载全部关联-随机 +func (r *QuestionQaItemDao) GetQuestionQaItemPreloadListRand(maps interface{}) (m []*model.QuestionQaItem, err error) { + err = global.Db.Preload(clause.Associations).Where(maps).Order("rand()").Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + // GetQuestionQaItemListRand 获取列表-随机 func (r *QuestionQaItemDao) GetQuestionQaItemListRand(maps interface{}, limit int) (m []*model.QuestionQaItem, err error) { err = global.Db.Where(maps).Limit(limit).Order("rand()").Find(&m).Error diff --git a/api/dto/Share.go b/api/dto/Share.go index 8af640d..6f20023 100644 --- a/api/dto/Share.go +++ b/api/dto/Share.go @@ -26,8 +26,8 @@ type ShareDtoForTwo struct { // ShareDtoForThree 获取返回数据-多轮固定题型模式 type ShareDtoForThree struct { - Single *ShareDto `json:"single"` // 单选题 - Multiple *ShareDto `json:"multiple"` // 多选题 - Judge *ShareDto `json:"judge"` // 判断题 - Qa *ShareDto `json:"qa"` // 问答题 + Single *ShareDtoForTwo `json:"single"` // 单选题 + Multiple *ShareDtoForTwo `json:"multiple"` // 多选题 + Judge *ShareDtoForTwo `json:"judge"` // 判断题 + Qa *ShareDtoForTwo `json:"qa"` // 问答题 } diff --git a/api/service/QuestionQa.go b/api/service/QuestionQa.go index 1eef6da..8a35778 100644 --- a/api/service/QuestionQa.go +++ b/api/service/QuestionQa.go @@ -11,7 +11,6 @@ import ( "knowledge/api/requests" "knowledge/global" "knowledge/utils" - "math/rand" "strconv" "time" ) @@ -944,12 +943,7 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeTwo(questionQa *model.Quest maps = make(map[string]interface{}) maps["qa_id"] = questionQa.QaId maps["is_must_select"] = 0 - notMustQuestions, err := questionQaItemDao.GetQuestionQaItemPreloadList(maps) - - // 打乱数据 - rand.Shuffle(len(notMustQuestions), func(i, j int) { - notMustQuestions[i], notMustQuestions[j] = notMustQuestions[j], notMustQuestions[i] - }) + notMustQuestions, err := questionQaItemDao.GetQuestionQaItemPreloadListRand(maps) // json转结构体-飞花令题目数量规则 var tokenQuestionContents []tokenQuestionContent @@ -966,9 +960,9 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeTwo(questionQa *model.Quest g.BaseTokenItem = dto.GetBaseTokenItemListDto(baseTokenItems) - // 先放入question中,题目数量不可大于规则的数量 - // 然后吧question转换为dto。 - // 最后在吧dto转为g + // 已被使用id集合 + var isUseQuestionId []int64 + // 飞花令数量 for i := 0; i < *questionQa.TokenNum; i++ { // 题目数据 @@ -979,7 +973,7 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeTwo(questionQa *model.Quest // 必选数据 for _, v3 := range mustQuestions { // 此处标识已用过 - if v3 == nil { + if utils.IsInSlice(v3.QuestionId, isUseQuestionId) { continue } @@ -993,7 +987,7 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeTwo(questionQa *model.Quest questions = append(questions, v3.Question) // 标记已被使用 - v3 = nil + isUseQuestionId = append(isUseQuestionId, v3.QuestionId) } } @@ -1003,19 +997,22 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeTwo(questionQa *model.Quest // 非必选数据 for _, v3 := range notMustQuestions { // 此处标识已用过 - if v3 == nil { + if utils.IsInSlice(v3.QuestionId, isUseQuestionId) { continue } - // 当数量超出时,跳出 - if len(questions) >= v2.Quantity { - continue + // 类型相同,加入该组数据中 + if v2.QuestionType == v3.Question.QuestionType { + // 当数量超出时,跳出 + if len(questions) >= v2.Quantity { + continue + } + + questions = append(questions, v3.Question) + + // 标记已被使用 + isUseQuestionId = append(isUseQuestionId, v3.QuestionId) } - - questions = append(questions, v3.Question) - - // 标记已被使用 - v3 = nil } } } @@ -1075,12 +1072,7 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.Que maps = make(map[string]interface{}) maps["qa_id"] = questionQa.QaId maps["is_must_select"] = 0 - notMustQuestions, err := questionQaItemDao.GetQuestionQaItemPreloadList(maps) - - // 打乱数据 - rand.Shuffle(len(notMustQuestions), func(i, j int) { - notMustQuestions[i], notMustQuestions[j] = notMustQuestions[j], notMustQuestions[i] - }) + notMustQuestions, err := questionQaItemDao.GetQuestionQaItemPreloadListRand(maps) // json转结构体-飞花令题目数量规则 var tokenQuestionContents []tokenQuestionContent @@ -1090,11 +1082,21 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.Que } // 获取题库飞花令数据-列表 - baseTokenItems, err := r.GetQuestionQaBaseTokenItemList(questionQa.QaDisplayType, questionQa.QaId, *questionQa.TokenNum) + maxTokenQuestionQuantity := 0 + for _, content := range tokenQuestionContents { + if content.Quantity > maxTokenQuestionQuantity { + maxTokenQuestionQuantity = content.Quantity + } + } + + baseTokenItemQuantity := maxTokenQuestionQuantity * *questionQa.TokenNum + baseTokenItems, err := r.GetQuestionQaBaseTokenItemList(questionQa.QaDisplayType, questionQa.QaId, baseTokenItemQuantity) if err != nil { return g, errors.New(err.Error()) } + // 已被使用id集合 + var isUseQuestionId []int64 for i := 0; i < *questionQa.RoundNum; i++ { // 单轮次返回值 shareDtoForThree := &dto.ShareDtoForThree{ @@ -1104,17 +1106,17 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.Que Qa: nil, } - shareDto := &dto.ShareDto{} - // 套题规则 [{"question_type":1,"quantity":10},{"question_type":2,"quantity":0},{"question_type":3,"quantity":0},{"question_type":4,"quantity":0}] for _, v2 := range tokenQuestionContents { + shareDtoForTwo := &dto.ShareDtoForTwo{} + // 题目数据 var questions []*model.Question // 必选数据 for _, v3 := range mustQuestions { // 此处标识已用过 - if v3 == nil { + if utils.IsInSlice(v3.QuestionId, isUseQuestionId) { continue } @@ -1128,7 +1130,7 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.Que questions = append(questions, v3.Question) // 标记已被使用 - v3 = nil + isUseQuestionId = append(isUseQuestionId, v3.QuestionId) } } @@ -1138,22 +1140,28 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.Que // 非必选数据 for _, v3 := range notMustQuestions { // 此处标识已用过 - if v3 == nil { + if utils.IsInSlice(v3.QuestionId, isUseQuestionId) { continue } - // 当数量超出时,跳出 - if len(questions) >= v2.Quantity { - continue + // 类型相同,加入该组数据中 + if v2.QuestionType == v3.Question.QuestionType { + // 当数量超出时,跳出 + if len(questions) >= v2.Quantity { + continue + } + + questions = append(questions, v3.Question) + + // 标记已被使用 + isUseQuestionId = append(isUseQuestionId, v3.QuestionId) } - - questions = append(questions, v3.Question) - - // 标记已被使用 - v3 = nil } } + // 处理返回值 + var questionDtoList []*dto.QuestionDto + // 处理数据 for _, v3 := range questions { questionOptionDao := dao.QuestionOptionDao{} @@ -1176,26 +1184,28 @@ func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.Que // 加载答案 questionDto.LoadQuestionAnswer(v3) - shareDto.Question = append(shareDto.Question, questionDto) + questionDtoList = append(questionDtoList, questionDto) } + shareDtoForTwo.Question = append(shareDtoForTwo.Question, questionDtoList) + // 处理对应飞花令数据 for _, item := range baseTokenItems { - if len(shareDto.BaseTokenItem) < v2.Quantity { + if len(shareDtoForTwo.BaseTokenItem) < (v2.Quantity * *questionQa.RoundNum) { questionDto := dto.GetBaseTokenItemDto(item) - shareDto.BaseTokenItem = append(shareDto.BaseTokenItem, questionDto) + shareDtoForTwo.BaseTokenItem = append(shareDtoForTwo.BaseTokenItem, questionDto) } } // 填入对应类别 if v2.QuestionType == 1 { - shareDtoForThree.Single = shareDto + shareDtoForThree.Single = shareDtoForTwo } else if v2.QuestionType == 2 { - shareDtoForThree.Multiple = shareDto - } else if v2.QuestionType == 2 { - shareDtoForThree.Judge = shareDto - } else if v2.QuestionType == 2 { - shareDtoForThree.Qa = shareDto + shareDtoForThree.Multiple = shareDtoForTwo + } else if v2.QuestionType == 3 { + shareDtoForThree.Judge = shareDtoForTwo + } else if v2.QuestionType == 4 { + shareDtoForThree.Qa = shareDtoForTwo } else { return g, errors.New("内部错误") } diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..1f1d242 --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,11 @@ +package utils + +// IsInSlice 判断目标值是否存在于切片中 +func IsInSlice(value int64, slice []int64) bool { + for _, v := range slice { + if v == value { + return true + } + } + return false +}