1408 lines
38 KiB
Go
1408 lines
38 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/goccy/go-json"
|
|
"gorm.io/gorm"
|
|
"knowledge/api/dao"
|
|
"knowledge/api/dto"
|
|
"knowledge/api/model"
|
|
"knowledge/api/requests"
|
|
"knowledge/global"
|
|
"knowledge/utils"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type QuestionQaService struct {
|
|
}
|
|
|
|
// 题库-飞花令题目数量规则
|
|
type tokenQuestionContent struct {
|
|
QuestionType int `json:"question_type"` // 题目类型(1:单选 2:多选 3:问答 4:判断)
|
|
Quantity int `json:"quantity"` // 数量
|
|
}
|
|
|
|
// AddQuestionQa 新增问答题库
|
|
func (r *QuestionQaService) AddQuestionQa(req requests.AddQuestionQa) (bool, error) {
|
|
// 处理图片
|
|
if req.Image != "" {
|
|
req.Image = utils.RemoveOssDomain(req.Image)
|
|
}
|
|
|
|
// 验证过期时间
|
|
now := time.Now()
|
|
// 1:绝对时效
|
|
// 获取本地时区
|
|
location, err := time.LoadLocation("Local")
|
|
if err != nil {
|
|
return false, errors.New("新增失败")
|
|
}
|
|
|
|
qaExpireTime, err := time.ParseInLocation("2006-01-02 15:04", req.QaExpireTime, location)
|
|
if err != nil {
|
|
return false, errors.New("过期时间错误")
|
|
}
|
|
|
|
if qaExpireTime.Before(now) {
|
|
return false, errors.New("过期时间需大于当前时间")
|
|
}
|
|
|
|
// 处理明细选题规则
|
|
questionQaItemContent, err := json.Marshal(req.QuestionQaItem)
|
|
if err != nil {
|
|
return false, errors.New("明细题目错误")
|
|
}
|
|
|
|
// 获取并检测题库题目数量
|
|
qaQuantity, err := r.CheckAddQaQuestionQuantity(req)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
// 检测题目明细重复问题
|
|
var items []*requests.QuestionQaItem
|
|
for _, v := range req.QuestionQaItem {
|
|
if r.CheckQuestionQaItemRepeat(items, v) {
|
|
items = append(items, v)
|
|
} else {
|
|
return false, errors.New(utils.QuestionType(v.QuestionType) + "选题存在冲突")
|
|
}
|
|
}
|
|
|
|
// 开始事务
|
|
tx := global.Db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
// 新增题目
|
|
questionQa := &model.QuestionQa{
|
|
QaName: req.QaName,
|
|
QaType: req.QaType,
|
|
QaQuantity: qaQuantity,
|
|
QaStatus: 1,
|
|
QaRuleContent: req.QaRuleContent,
|
|
TokenNum: nil,
|
|
RoundNum: nil,
|
|
QaDisplayType: req.QaDisplayType,
|
|
IsTurnTimer: req.IsTurnTimer,
|
|
QaExpireTime: model.LocalTime(qaExpireTime),
|
|
QaPassword: req.QaPassword,
|
|
OpenNumber: 0,
|
|
Image: req.Image,
|
|
ItemContent: string(questionQaItemContent),
|
|
}
|
|
|
|
// 固定套题模式-飞花令数量
|
|
if req.QaType == 2 {
|
|
questionQa.TokenNum = req.TokenNum
|
|
}
|
|
|
|
// 多轮固定题型模式-飞花令数量、轮次数量
|
|
if req.QaType == 3 {
|
|
questionQa.TokenNum = req.TokenNum
|
|
questionQa.RoundNum = req.RoundNum
|
|
}
|
|
|
|
if req.QaType == 2 || req.QaType == 3 {
|
|
// 处理飞花令题目数量规则
|
|
tokenQuestionContent, err := json.Marshal(req.TokenQuestionContent)
|
|
if err != nil {
|
|
return false, errors.New("飞花令题目数量错误")
|
|
}
|
|
|
|
questionQa.TokenQuestionContent = string(tokenQuestionContent)
|
|
}
|
|
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
questionQa, err = questionQaDao.AddQuestionQa(tx, questionQa)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("新增失败")
|
|
}
|
|
|
|
// 新增飞花令标签数据
|
|
if req.QaDisplayType == 2 {
|
|
questionQaTokenDao := dao.QuestionQaTokenDao{}
|
|
baseTokenDao := dao.BaseTokenDao{}
|
|
baseTokenItemDao := dao.BaseTokenItemDao{}
|
|
|
|
// 飞花令明细总数
|
|
tokenItemQuantity := 0
|
|
for i, item := range req.BaseTokenItem {
|
|
tokenId, err := strconv.ParseInt(item.TokenId, 10, 64)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 检测飞花令基础数据
|
|
_, err = baseTokenDao.GetBaseTokenById(tokenId)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 获取飞花令明细数据
|
|
baseTokenItem, err := baseTokenItemDao.GetBaseTokenItemListByTokenId(tokenId)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 飞花令明细总数
|
|
tokenItemQuantity = tokenItemQuantity + len(baseTokenItem)
|
|
|
|
questionQaToken := &model.QuestionQaToken{
|
|
QaId: questionQa.QaId,
|
|
TokenId: tokenId,
|
|
Sort: i + 1,
|
|
}
|
|
|
|
questionQaToken, err = questionQaTokenDao.AddQuestionQaToken(tx, questionQaToken)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
// 检测飞花令数量
|
|
if req.QaType == 1 {
|
|
// 所需飞花令数量 = 题目总数
|
|
if tokenItemQuantity < qaQuantity {
|
|
tx.Rollback()
|
|
return false, errors.New("选择的飞花令的数量需大于:" + fmt.Sprintf("%d", qaQuantity))
|
|
}
|
|
}
|
|
|
|
if req.QaType == 2 {
|
|
// 所需飞花令数量 = TokenNum
|
|
if tokenItemQuantity < *req.TokenNum {
|
|
tx.Rollback()
|
|
return false, errors.New("选择的飞花令的数量需大于:" + fmt.Sprintf("%d", *req.TokenNum))
|
|
}
|
|
}
|
|
|
|
if req.QaType == 3 {
|
|
//// 轮次 * 最大值 = 所需飞花令数量
|
|
//maxTokenQuestionQuantity := 0
|
|
//for _, content := range req.TokenQuestionContent {
|
|
// if content.Quantity > maxTokenQuestionQuantity {
|
|
// maxTokenQuestionQuantity = content.Quantity
|
|
// }
|
|
//}
|
|
|
|
if tokenItemQuantity < *req.TokenNum {
|
|
tx.Rollback()
|
|
return false, errors.New("选择的飞花令的数量需大于:" + fmt.Sprintf("%d", *req.TokenNum))
|
|
}
|
|
}
|
|
}
|
|
|
|
// 生成分享链接
|
|
questionQaData := make(map[string]interface{})
|
|
questionQaData["qa_share_id"] = utils.GenerateUniqueCode()
|
|
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("新增失败")
|
|
}
|
|
|
|
questionDao := dao.QuestionDao{}
|
|
questionQaItemDao := dao.QuestionQaItemDao{}
|
|
|
|
var notQuestionIds []int64 // 处理需排除的题目id
|
|
if len(req.RepeatQaId) > 0 {
|
|
// 获取正常题库的明细列表
|
|
var repeatQaId []string
|
|
for _, item := range req.RepeatQaId {
|
|
repeatQaId = append(repeatQaId, item.QaId)
|
|
}
|
|
questionQaItems, _ := questionQaItemDao.GetQuestionQaItemListByQaIdDistinctQuestionId(repeatQaId)
|
|
if len(questionQaItems) > 0 {
|
|
for _, item := range questionQaItems {
|
|
notQuestionIds = append(notQuestionIds, item.QuestionId)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 新增问答题库题目列表
|
|
for _, item := range req.QuestionQaItem {
|
|
// 验证数量
|
|
maps := make(map[string]interface{})
|
|
maps["question_type"] = item.QuestionType
|
|
maps["question_status"] = 1
|
|
maps["is_delete"] = 0
|
|
maps["question_source"] = 1
|
|
if item.Difficulty != nil {
|
|
maps["difficulty"] = item.Difficulty
|
|
}
|
|
maps["first_label_id"] = item.FirstLabelId
|
|
if item.SecondLabelId != "" {
|
|
maps["second_label_id"] = item.SecondLabelId
|
|
}
|
|
|
|
// 获取随机明细题目
|
|
questions, err := questionDao.GetQuestionNotInListRand(maps, notQuestionIds, item.Quantity)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
if len(questions) < item.Quantity {
|
|
tx.Rollback()
|
|
return false, errors.New(utils.QuestionType(item.QuestionType) + "数量不足")
|
|
}
|
|
|
|
// 新增明细题目
|
|
for _, question := range questions {
|
|
questionQaItem := &model.QuestionQaItem{
|
|
QaId: questionQa.QaId,
|
|
QuestionId: question.QuestionId,
|
|
}
|
|
questionQaItem, err := questionQaItemDao.AddQuestionQaItem(tx, questionQaItem)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("新增失败")
|
|
}
|
|
}
|
|
}
|
|
|
|
// 新增计时设置
|
|
if req.IsTurnTimer == 1 {
|
|
questionQaTimerDao := dao.QuestionQaTimerDao{}
|
|
for _, timer := range req.QuestionQaTimer {
|
|
QuestionQaTimer := &model.QuestionQaTimer{
|
|
QaId: questionQa.QaId,
|
|
QuestionType: timer.QuestionType,
|
|
TimerRule: timer.TimerRule,
|
|
Duration: timer.Duration,
|
|
}
|
|
|
|
QuestionQaTimer, err := questionQaTimerDao.AddQuestionQaTimer(tx, QuestionQaTimer)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("新增失败")
|
|
}
|
|
}
|
|
}
|
|
|
|
tx.Commit()
|
|
return true, nil
|
|
}
|
|
|
|
// PutQuestionQa 修改题目题库
|
|
func (r *QuestionQaService) PutQuestionQa(qaId int64, req requests.PutQuestionQa) (bool, error) {
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
questionDao := dao.QuestionDao{}
|
|
|
|
questionQa, err := questionQaDao.GetQuestionQaById(qaId)
|
|
if err != nil {
|
|
return false, errors.New("题库不存在")
|
|
}
|
|
|
|
if questionQa.QaStatus == 2 {
|
|
return false, errors.New("题库已失效,请重新创建")
|
|
}
|
|
|
|
// 开始事务
|
|
tx := global.Db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
questionQaData := make(map[string]interface{})
|
|
|
|
// 名称
|
|
if req.QaName != questionQa.QaName {
|
|
questionQaData["qa_name"] = req.QaName
|
|
}
|
|
|
|
// 规则解释
|
|
if req.QaRuleContent != questionQa.QaRuleContent {
|
|
questionQaData["qa_rule_content"] = req.QaRuleContent
|
|
}
|
|
|
|
// 展示类型
|
|
if req.QaDisplayType != questionQa.QaDisplayType {
|
|
questionQaData["qa_display_type"] = req.QaDisplayType
|
|
}
|
|
|
|
// 验证过期时间
|
|
now := time.Now()
|
|
// 1:绝对时效
|
|
// 获取本地时区
|
|
location, err := time.LoadLocation("Local")
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("新增失败")
|
|
}
|
|
|
|
qaExpireTime, err := time.ParseInLocation("2006-01-02 15:04", req.QaExpireTime, location)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("过期时间错误")
|
|
}
|
|
|
|
if qaExpireTime.Before(now) {
|
|
tx.Rollback()
|
|
return false, errors.New("过期时间需大于当前时间")
|
|
}
|
|
|
|
questionQaData["qa_expire_time"] = model.LocalTime(qaExpireTime)
|
|
|
|
// 分享密码
|
|
if req.QaPassword != questionQa.QaPassword {
|
|
questionQaData["qa_password"] = req.QaPassword
|
|
}
|
|
|
|
// 是否允许重复
|
|
if len(req.RepeatQaId) > 0 {
|
|
var repeatQaId []string
|
|
for _, item := range req.RepeatQaId {
|
|
repeatQaId = append(repeatQaId, item.QaId)
|
|
}
|
|
|
|
repeatQaIdStr := strings.Join(repeatQaId, ",")
|
|
if repeatQaIdStr != questionQa.RepeatQaId {
|
|
questionQaData["repeat_qa_id"] = req.RepeatQaId
|
|
}
|
|
}
|
|
|
|
// 背景图
|
|
image := utils.RemoveOssDomain(req.Image)
|
|
if image != questionQa.Image {
|
|
questionQaData["image"] = image
|
|
}
|
|
|
|
// 处理飞花令题目数量规则
|
|
tokenQuestionContent, _ := json.Marshal(req.TokenQuestionContent)
|
|
if string(tokenQuestionContent) != questionQa.TokenQuestionContent {
|
|
questionQaData["token_question_content"] = string(tokenQuestionContent)
|
|
}
|
|
|
|
// 获取并检测题库题目数量
|
|
qaQuantity, err := r.CheckPutQaQuestionQuantity(req)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 题目数量
|
|
if qaQuantity != questionQa.QaQuantity {
|
|
if req.Action == 1 {
|
|
tx.Rollback()
|
|
return false, errors.New("您修改了题目数量,无法正常修改该题库,请重新生成")
|
|
}
|
|
|
|
questionQaData["qa_quantity"] = qaQuantity
|
|
|
|
if req.QaType == 2 {
|
|
questionQaData["token_num"] = req.TokenNum
|
|
}
|
|
|
|
if req.QaType == 3 {
|
|
questionQaData["token_num"] = req.TokenNum
|
|
questionQaData["round_num"] = req.RoundNum
|
|
}
|
|
}
|
|
|
|
// 处理题库明细-需重新生成时才会检测明细
|
|
if req.Action == 2 {
|
|
// 检测题目明细重复问题
|
|
var items []*requests.QuestionQaItem
|
|
for _, v := range req.QuestionQaItem {
|
|
if r.CheckQuestionQaItemRepeat(items, v) {
|
|
items = append(items, v)
|
|
} else {
|
|
return false, errors.New(utils.QuestionType(v.QuestionType) + ":选题存在冲突")
|
|
}
|
|
}
|
|
|
|
// 删除所有明细
|
|
questionQaItemDao := dao.QuestionQaItemDao{}
|
|
err := questionQaItemDao.DeleteQuestionQaItemByQaId(tx, questionQa.QaId)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
var notQuestionIds []int64 // 处理需排除的题目id
|
|
if len(req.RepeatQaId) > 0 {
|
|
// 获取正常题库的明细列表
|
|
var repeatQaId []string
|
|
for _, item := range req.RepeatQaId {
|
|
repeatQaId = append(repeatQaId, item.QaId)
|
|
}
|
|
questionQaItems, _ := questionQaItemDao.GetQuestionQaItemListByQaIdDistinctQuestionId(repeatQaId)
|
|
if len(questionQaItems) > 0 {
|
|
for _, item := range questionQaItems {
|
|
notQuestionIds = append(notQuestionIds, item.QuestionId)
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, item := range req.QuestionQaItem {
|
|
// 验证数量
|
|
maps := make(map[string]interface{})
|
|
maps["question_type"] = item.QuestionType
|
|
maps["question_status"] = 1
|
|
maps["is_delete"] = 0
|
|
maps["question_source"] = 1
|
|
if item.Difficulty != nil {
|
|
maps["difficulty"] = item.Difficulty
|
|
}
|
|
maps["first_label_id"] = item.FirstLabelId
|
|
if item.SecondLabelId != "" {
|
|
maps["second_label_id"] = item.SecondLabelId
|
|
}
|
|
|
|
// 获取随机明细题目
|
|
//questions, err := questionDao.GetQuestionListRand(maps, item.Quantity)
|
|
questions, err := questionDao.GetQuestionNotInListRand(maps, notQuestionIds, item.Quantity)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
if len(questions) < item.Quantity {
|
|
tx.Rollback()
|
|
return false, errors.New("选题超出现有题目数量")
|
|
}
|
|
|
|
for _, question := range questions {
|
|
questionQaItem := &model.QuestionQaItem{
|
|
QaId: questionQa.QaId,
|
|
QuestionId: question.QuestionId,
|
|
}
|
|
questionQaItem, err := questionQaItemDao.AddQuestionQaItem(tx, questionQaItem)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("新增失败")
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理明细选题规则
|
|
questionQaItemContent, err := json.Marshal(req.QuestionQaItem)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
if string(questionQaItemContent) != questionQa.ItemContent {
|
|
questionQaData["item_content"] = string(questionQaItemContent)
|
|
}
|
|
}
|
|
|
|
// 计时开关
|
|
if req.IsTurnTimer != questionQa.IsTurnTimer {
|
|
questionQaData["is_turn_timer"] = req.IsTurnTimer
|
|
}
|
|
|
|
if len(questionQaData) > 0 {
|
|
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New(err.Error())
|
|
}
|
|
}
|
|
|
|
// 删除飞花令
|
|
questionQaTokenDao := dao.QuestionQaTokenDao{}
|
|
maps := make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
err = questionQaTokenDao.DeleteQuestionQaToken(tx, maps)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New(err.Error())
|
|
}
|
|
|
|
// 新增飞花令
|
|
if req.QaDisplayType == 2 {
|
|
baseTokenDao := dao.BaseTokenDao{}
|
|
baseTokenItemDao := dao.BaseTokenItemDao{}
|
|
|
|
// 飞花令明细总数
|
|
tokenItemQuantity := 0
|
|
for i, item := range req.BaseTokenItem {
|
|
tokenId, err := strconv.ParseInt(item.TokenId, 10, 64)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 检测飞花令基础数据
|
|
_, err = baseTokenDao.GetBaseTokenById(tokenId)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 获取飞花令明细数据
|
|
baseTokenItem, err := baseTokenItemDao.GetBaseTokenItemListByTokenId(tokenId)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
|
|
// 飞花令明细总数
|
|
tokenItemQuantity = tokenItemQuantity + len(baseTokenItem)
|
|
|
|
questionQaToken := &model.QuestionQaToken{
|
|
QaId: questionQa.QaId,
|
|
TokenId: tokenId,
|
|
Sort: i + 1,
|
|
}
|
|
|
|
questionQaToken, err = questionQaTokenDao.AddQuestionQaToken(tx, questionQaToken)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
// 检测飞花令数量
|
|
if req.QaType == 1 {
|
|
// 所需飞花令数量 = 题目总数
|
|
if tokenItemQuantity < qaQuantity {
|
|
tx.Rollback()
|
|
return false, errors.New("选择的飞花令的数量需大于:" + fmt.Sprintf("%d", qaQuantity))
|
|
}
|
|
}
|
|
|
|
if req.QaType == 2 {
|
|
// 所需飞花令数量 = TokenNum
|
|
if tokenItemQuantity < *req.TokenNum {
|
|
tx.Rollback()
|
|
return false, errors.New("选择的飞花令的数量需大于:" + fmt.Sprintf("%d", *req.TokenNum))
|
|
}
|
|
}
|
|
|
|
if req.QaType == 3 {
|
|
//// 轮次 * 最大值 = 所需飞花令数量
|
|
//maxTokenQuestionQuantity := 0
|
|
//for _, content := range req.TokenQuestionContent {
|
|
// if content.Quantity > maxTokenQuestionQuantity {
|
|
// maxTokenQuestionQuantity = content.Quantity
|
|
// }
|
|
//}
|
|
|
|
if tokenItemQuantity < *req.TokenNum {
|
|
tx.Rollback()
|
|
return false, errors.New("选择的飞花令的数量需大于:" + fmt.Sprintf("%d", *req.TokenNum))
|
|
}
|
|
}
|
|
}
|
|
|
|
// 删除计时规则
|
|
questionQaTimerDao := dao.QuestionQaTimerDao{}
|
|
err = questionQaTimerDao.DeleteQuestionQaTimerByQaId(tx, questionQa.QaId)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New(err.Error())
|
|
}
|
|
|
|
// 新增计时规则
|
|
if req.IsTurnTimer == 1 {
|
|
for _, timer := range req.QuestionQaTimer {
|
|
QuestionQaTimer := &model.QuestionQaTimer{
|
|
QaId: questionQa.QaId,
|
|
QuestionType: timer.QuestionType,
|
|
TimerRule: timer.TimerRule,
|
|
Duration: timer.Duration,
|
|
}
|
|
|
|
QuestionQaTimer, err := questionQaTimerDao.AddQuestionQaTimer(tx, QuestionQaTimer)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New("修改失败")
|
|
}
|
|
}
|
|
}
|
|
|
|
tx.Commit()
|
|
return true, nil
|
|
}
|
|
|
|
// PutQuestionQaPassword 修改题目题库密码
|
|
func (r *QuestionQaService) PutQuestionQaPassword(qaId int64, req requests.PutQuestionQaPassword) (bool, error) {
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
questionQa, err := questionQaDao.GetQuestionQaById(qaId)
|
|
if err != nil {
|
|
return false, errors.New("题库不存在")
|
|
}
|
|
|
|
if questionQa.QaStatus == 2 {
|
|
return false, errors.New("题库已失效")
|
|
}
|
|
|
|
// 分享密码
|
|
if req.QaPassword == questionQa.QaPassword {
|
|
return true, nil
|
|
}
|
|
|
|
// 开始事务
|
|
tx := global.Db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
questionQaData := make(map[string]interface{})
|
|
questionQaData["qa_password"] = req.QaPassword
|
|
|
|
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New(err.Error())
|
|
}
|
|
|
|
tx.Commit()
|
|
return true, nil
|
|
}
|
|
|
|
// PutQuestionQaExpire 修改问答题库有效期
|
|
func (r *QuestionQaService) PutQuestionQaExpire(qaId int64, req requests.PutQuestionQaExpire) (bool, error) {
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
questionQa, err := questionQaDao.GetQuestionQaById(qaId)
|
|
if err != nil {
|
|
return false, errors.New("题库不存在")
|
|
}
|
|
|
|
if questionQa.QaStatus == 2 {
|
|
return false, errors.New("题库已失效")
|
|
}
|
|
|
|
// 验证过期时间
|
|
now := time.Now()
|
|
|
|
// 获取本地时区
|
|
location, err := time.LoadLocation("Local")
|
|
if err != nil {
|
|
return false, errors.New("修改失败")
|
|
}
|
|
|
|
qaExpireTime, err := time.ParseInLocation("2006-01-02 15:04", req.QaExpireTime, location)
|
|
if err != nil {
|
|
return false, errors.New("过期时间错误")
|
|
}
|
|
|
|
if qaExpireTime.Before(now) {
|
|
return false, errors.New("过期时间需大于当前时间")
|
|
}
|
|
|
|
// 开始事务
|
|
tx := global.Db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
questionQaData := make(map[string]interface{})
|
|
questionQaData["qa_expire_time"] = qaExpireTime
|
|
|
|
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New(err.Error())
|
|
}
|
|
|
|
tx.Commit()
|
|
return true, nil
|
|
}
|
|
|
|
// PutQuestionQaRule 修改问答题库规则解释
|
|
func (r *QuestionQaService) PutQuestionQaRule(qaId int64, req requests.PutQuestionQaRule) (bool, error) {
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
questionQa, err := questionQaDao.GetQuestionQaById(qaId)
|
|
if err != nil {
|
|
return false, errors.New("题库不存在")
|
|
}
|
|
|
|
if questionQa.QaStatus == 2 {
|
|
return false, errors.New("题库已失效")
|
|
}
|
|
|
|
// 分享密码
|
|
if req.QaRuleContent == questionQa.QaRuleContent {
|
|
return true, nil
|
|
}
|
|
|
|
// 开始事务
|
|
tx := global.Db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
questionQaData := make(map[string]interface{})
|
|
questionQaData["qa_rule_content"] = req.QaRuleContent
|
|
|
|
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return false, errors.New(err.Error())
|
|
}
|
|
|
|
tx.Commit()
|
|
return true, nil
|
|
}
|
|
|
|
// RecordQuestionQaOpenNum 记录问答题库打开次数
|
|
func (r *QuestionQaService) RecordQuestionQaOpenNum(tx *gorm.DB, qaId int64) error {
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
err := questionQaDao.Inc(tx, qaId, "open_number", 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CheckAddQaQuestionQuantity 检测题库题目数量-新增
|
|
func (r *QuestionQaService) CheckAddQaQuestionQuantity(req requests.AddQuestionQa) (qaQuantity int, err error) {
|
|
// 题目总数量
|
|
qaQuantity = req.QaQuantity
|
|
|
|
// 选择的明细总数量 += QuestionQaItem.Quantity
|
|
itemQuantity := 0
|
|
for _, item := range req.QuestionQaItem {
|
|
itemQuantity = itemQuantity + item.Quantity
|
|
}
|
|
|
|
// 常规模式
|
|
if req.QaType == 1 {
|
|
// 总数量 需大于 选择的明细数量
|
|
if qaQuantity > itemQuantity {
|
|
return qaQuantity, errors.New("明细题目数量需超过题库所需题目总数量")
|
|
}
|
|
}
|
|
|
|
// 固定套题模式
|
|
if req.QaType == 2 {
|
|
// 计算飞花令题目数量
|
|
tokenQuestionQuantity := 0
|
|
for _, content := range req.TokenQuestionContent {
|
|
tokenQuestionQuantity = tokenQuestionQuantity + content.Quantity
|
|
}
|
|
|
|
// 总数量 = 飞花令题目数量 * 飞花令数量
|
|
qaQuantity = tokenQuestionQuantity * *req.TokenNum
|
|
if qaQuantity > itemQuantity {
|
|
return qaQuantity, errors.New("明细题目数量需超过题库所需题目总数量")
|
|
}
|
|
|
|
// 单个类型总数量 = 单一题目类型数量 * 飞花令数量
|
|
for _, content := range req.TokenQuestionContent {
|
|
itemQuantity = 0
|
|
for _, item := range req.QuestionQaItem {
|
|
if content.QuestionType == item.QuestionType {
|
|
itemQuantity = itemQuantity + item.Quantity
|
|
}
|
|
}
|
|
|
|
quantity := content.Quantity * *req.TokenNum
|
|
|
|
if quantity > itemQuantity {
|
|
return qaQuantity, errors.New(utils.QuestionType(content.QuestionType) + "数量不足")
|
|
}
|
|
}
|
|
}
|
|
|
|
// 多轮固定题型模式
|
|
if req.QaType == 3 {
|
|
// 计算飞花令题目数量
|
|
tokenQuestionQuantity := 0
|
|
for _, content := range req.TokenQuestionContent {
|
|
tokenQuestionQuantity = tokenQuestionQuantity + content.Quantity
|
|
}
|
|
|
|
// 总数量 = 飞花令题目数量 * 飞花令数量 * 轮次
|
|
qaQuantity = tokenQuestionQuantity * *req.TokenNum * *req.RoundNum
|
|
if qaQuantity > itemQuantity {
|
|
return qaQuantity, errors.New("明细题目数量需超过题库所需题目总数量")
|
|
}
|
|
|
|
// 单个类型总数量 = 单一题目类型数量 * 飞花令数量 * 轮次
|
|
for _, content := range req.TokenQuestionContent {
|
|
itemQuantity = 0
|
|
for _, item := range req.QuestionQaItem {
|
|
if content.QuestionType == item.QuestionType {
|
|
itemQuantity = itemQuantity + item.Quantity
|
|
}
|
|
}
|
|
|
|
quantity := content.Quantity * *req.TokenNum * *req.RoundNum
|
|
|
|
if quantity > itemQuantity {
|
|
return qaQuantity, errors.New(utils.QuestionType(content.QuestionType) + "数量不足")
|
|
}
|
|
}
|
|
}
|
|
|
|
return qaQuantity, nil
|
|
}
|
|
|
|
// CheckPutQaQuestionQuantity 检测题库题目数量-修改
|
|
func (r *QuestionQaService) CheckPutQaQuestionQuantity(req requests.PutQuestionQa) (qaQuantity int, err error) {
|
|
// 题目总数量
|
|
qaQuantity = req.QaQuantity
|
|
|
|
// 选择的明细总数量 += QuestionQaItem.Quantity
|
|
itemQuantity := 0
|
|
for _, item := range req.QuestionQaItem {
|
|
itemQuantity = itemQuantity + item.Quantity
|
|
}
|
|
|
|
// 常规模式
|
|
if req.QaType == 1 {
|
|
// 总数量 需大于 选择的明细数量
|
|
if qaQuantity > itemQuantity {
|
|
return qaQuantity, errors.New("明细题目数量需超过题库所需题目总数量")
|
|
}
|
|
}
|
|
|
|
// 固定套题模式
|
|
if req.QaType == 2 {
|
|
// 计算飞花令题目数量
|
|
tokenQuestionQuantity := 0
|
|
for _, content := range req.TokenQuestionContent {
|
|
tokenQuestionQuantity = tokenQuestionQuantity + content.Quantity
|
|
}
|
|
|
|
// 总数量 = 飞花令题目数量 * 飞花令数量
|
|
qaQuantity = tokenQuestionQuantity * *req.TokenNum
|
|
if qaQuantity > itemQuantity {
|
|
return qaQuantity, errors.New("明细题目数量需超过题库所需题目总数量")
|
|
}
|
|
|
|
// 单个类型总数量 = 单一题目类型数量 * 飞花令数量
|
|
for _, content := range req.TokenQuestionContent {
|
|
itemQuantity = 0
|
|
for _, item := range req.QuestionQaItem {
|
|
if content.QuestionType == item.QuestionType {
|
|
itemQuantity = itemQuantity + item.Quantity
|
|
}
|
|
}
|
|
|
|
quantity := content.Quantity * *req.TokenNum
|
|
|
|
if quantity > itemQuantity {
|
|
return qaQuantity, errors.New(utils.QuestionType(content.QuestionType) + "数量不足")
|
|
}
|
|
}
|
|
}
|
|
|
|
// 多轮固定题型模式
|
|
if req.QaType == 3 {
|
|
// 计算飞花令题目数量
|
|
tokenQuestionQuantity := 0
|
|
for _, content := range req.TokenQuestionContent {
|
|
tokenQuestionQuantity = tokenQuestionQuantity + content.Quantity
|
|
}
|
|
|
|
// 总数量 = 飞花令题目数量 * 飞花令数量 * 轮次
|
|
qaQuantity = tokenQuestionQuantity * *req.TokenNum * *req.RoundNum
|
|
if qaQuantity > itemQuantity {
|
|
return qaQuantity, errors.New("明细题目数量需超过题库所需题目总数量")
|
|
}
|
|
|
|
// 单个类型总数量 = 单一题目类型数量 * 飞花令数量 * 轮次
|
|
for _, content := range req.TokenQuestionContent {
|
|
itemQuantity = 0
|
|
for _, item := range req.QuestionQaItem {
|
|
if content.QuestionType == item.QuestionType {
|
|
itemQuantity = itemQuantity + item.Quantity
|
|
}
|
|
}
|
|
|
|
quantity := content.Quantity * *req.TokenNum * *req.RoundNum
|
|
|
|
if quantity > itemQuantity {
|
|
return qaQuantity, errors.New(utils.QuestionType(content.QuestionType) + "数量不足")
|
|
}
|
|
}
|
|
}
|
|
|
|
return qaQuantity, nil
|
|
}
|
|
|
|
// GetQuestionQaBaseTokenItemList 获取题库飞花令数据-列表
|
|
func (r *QuestionQaService) GetQuestionQaBaseTokenItemList(qaDisplayType int, qaId int64, quantity int) ([]*model.BaseTokenItem, error) {
|
|
// 定义返回值
|
|
var g []*model.BaseTokenItem
|
|
|
|
// 判断展示类型
|
|
if qaDisplayType != 2 {
|
|
return g, nil
|
|
}
|
|
|
|
questionQaTokenDao := dao.QuestionQaTokenDao{}
|
|
maps := make(map[string]interface{})
|
|
maps["qa_id"] = qaId
|
|
questionQaToken, err := questionQaTokenDao.GetQuestionQaTokenPreloadList(maps)
|
|
if err != nil {
|
|
return g, errors.New("内部错误")
|
|
}
|
|
|
|
for _, v := range questionQaToken {
|
|
// 处理返回值
|
|
for _, item := range v.BaseTokenItem {
|
|
if len(g) < quantity {
|
|
// 将转换后的结构体添加到新切片中
|
|
g = append(g, item)
|
|
}
|
|
}
|
|
}
|
|
|
|
return g, nil
|
|
}
|
|
|
|
// GetShareQuestionQaForTypeOne 获取题库数据-常规模式
|
|
func (r *QuestionQaService) GetShareQuestionQaForTypeOne(questionQa *model.QuestionQa) (*dto.ShareDto, error) {
|
|
// 初始化返回值
|
|
g := &dto.ShareDto{}
|
|
|
|
if questionQa.QaType != 1 {
|
|
return g, errors.New("题库类型错误")
|
|
}
|
|
|
|
questionQaItemDao := dao.QuestionQaItemDao{}
|
|
|
|
// 题目数据
|
|
var questions []*model.Question
|
|
|
|
// 题目数据-必备选中
|
|
maps := make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
maps["is_must_select"] = 1
|
|
questionQaItems, err := questionQaItemDao.GetQuestionQaItemWhereList(maps)
|
|
if err == nil && len(questionQaItems) > 0 {
|
|
for _, item := range questionQaItems {
|
|
questions = append(questions, item.Question)
|
|
}
|
|
}
|
|
|
|
// 题目数据-剩余随机数量
|
|
remainingQuantity := questionQa.QaQuantity - len(questionQaItems)
|
|
if remainingQuantity > 0 {
|
|
// 随机获取剩余题目
|
|
maps = make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
maps["is_must_select"] = 0
|
|
questionQaItems, err = questionQaItemDao.GetQuestionQaItemWhereListRandLimit(maps, remainingQuantity)
|
|
if err == nil && len(questionQaItems) > 0 {
|
|
for _, item := range questionQaItems {
|
|
questions = append(questions, item.Question)
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, v := range questions {
|
|
// 处理返回值
|
|
questionDto := dto.GetShareQuestionDto(v)
|
|
|
|
// 加载选项
|
|
questionDto.LoadQuestionOptionSimplify(v.QuestionOption)
|
|
|
|
// 加载图片
|
|
questionDto.LoadQuestionImage(v.QuestionImage)
|
|
|
|
// 加载答案
|
|
questionDto.LoadQuestionAnswer(v)
|
|
|
|
// 将转换后的结构体添加到新切片中
|
|
g.Question = append(g.Question, questionDto)
|
|
}
|
|
|
|
// 按照难度重新排序题目顺序
|
|
//sort.SliceStable(g.Question, func(i, j int) bool {
|
|
// return g.Question[i].Difficulty < g.Question[j].Difficulty
|
|
//})
|
|
|
|
// 获取题库飞花令数据
|
|
baseTokenItems, err := r.GetQuestionQaBaseTokenItemList(questionQa.QaDisplayType, questionQa.QaId, questionQa.QaQuantity)
|
|
if err != nil {
|
|
return g, errors.New(err.Error())
|
|
}
|
|
|
|
g.BaseTokenItem = dto.GetBaseTokenItemListDto(baseTokenItems)
|
|
|
|
return g, nil
|
|
}
|
|
|
|
// GetShareQuestionQaForTypeTwo 获取题库数据-固定套题模式
|
|
func (r *QuestionQaService) GetShareQuestionQaForTypeTwo(questionQa *model.QuestionQa) (*dto.ShareDtoForTwo, error) {
|
|
// 初始化返回值
|
|
g := &dto.ShareDtoForTwo{}
|
|
|
|
if questionQa.QaType != 2 {
|
|
return g, errors.New("题库类型错误")
|
|
}
|
|
|
|
questionQaItemDao := dao.QuestionQaItemDao{}
|
|
|
|
// 题目数据-必备选中
|
|
maps := make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
maps["is_must_select"] = 1
|
|
mustQuestions, err := questionQaItemDao.GetQuestionQaItemWhereList(maps)
|
|
|
|
// 题目数据-未比被选中
|
|
maps = make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
maps["is_must_select"] = 0
|
|
notMustQuestions, err := questionQaItemDao.GetQuestionQaItemWhereListRand(maps)
|
|
|
|
// json转结构体-飞花令题目数量规则
|
|
var tokenQuestionContents []tokenQuestionContent
|
|
err = json.Unmarshal([]byte(questionQa.TokenQuestionContent), &tokenQuestionContents)
|
|
if err != nil {
|
|
return g, errors.New(err.Error())
|
|
}
|
|
|
|
// 获取题库飞花令数据-列表
|
|
baseTokenItems, err := r.GetQuestionQaBaseTokenItemList(questionQa.QaDisplayType, questionQa.QaId, *questionQa.TokenNum)
|
|
if err != nil {
|
|
return g, errors.New(err.Error())
|
|
}
|
|
|
|
g.BaseTokenItem = dto.GetBaseTokenItemListDto(baseTokenItems)
|
|
|
|
// 已被使用id集合
|
|
var isUseQuestionId []int64
|
|
|
|
// 飞花令数量
|
|
for i := 0; i < *questionQa.TokenNum; i++ {
|
|
// 题目数据
|
|
var tokenQuestions []*model.Question
|
|
|
|
// 套题规则 [{"question_type":1,"quantity":10},{"question_type":2,"quantity":0},{"question_type":3,"quantity":0},{"question_type":4,"quantity":0}]
|
|
for _, v2 := range tokenQuestionContents {
|
|
var questions []*model.Question
|
|
|
|
// 必选数据
|
|
for _, v3 := range mustQuestions {
|
|
// 判断此题目是否已被选中
|
|
if utils.IsInSlice(v3.QuestionId, isUseQuestionId) {
|
|
continue
|
|
}
|
|
|
|
// 类型相同,加入该组数据中
|
|
if v2.QuestionType == v3.Question.QuestionType {
|
|
// 当数量超出时,跳出
|
|
if len(questions) >= v2.Quantity {
|
|
continue
|
|
}
|
|
|
|
questions = append(questions, v3.Question)
|
|
|
|
// 标记已被使用
|
|
isUseQuestionId = append(isUseQuestionId, v3.QuestionId)
|
|
}
|
|
}
|
|
|
|
// 题目数据-剩余随机数量
|
|
remainingQuantity := v2.Quantity - len(questions)
|
|
if remainingQuantity > 0 {
|
|
// 非必选数据
|
|
for _, v3 := range notMustQuestions {
|
|
// 判断此题目是否已被选中
|
|
if utils.IsInSlice(v3.QuestionId, isUseQuestionId) {
|
|
continue
|
|
}
|
|
|
|
// 类型相同,加入该组数据中
|
|
if v2.QuestionType == v3.Question.QuestionType {
|
|
// 当数量超出时,跳出
|
|
if len(questions) >= v2.Quantity {
|
|
continue
|
|
}
|
|
|
|
questions = append(questions, v3.Question)
|
|
|
|
// 标记已被使用
|
|
isUseQuestionId = append(isUseQuestionId, v3.QuestionId)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(questions) > 0 {
|
|
for _, v3 := range questions {
|
|
tokenQuestions = append(tokenQuestions, v3)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理返回值
|
|
questionDtoList := make([]*dto.QuestionDto, len(tokenQuestions))
|
|
|
|
// 处理数据
|
|
for i2, v2 := range tokenQuestions {
|
|
// 处理返回值
|
|
questionDto := dto.GetShareQuestionDto(v2)
|
|
|
|
// 加载选项
|
|
questionDto.LoadQuestionOptionSimplify(v2.QuestionOption)
|
|
|
|
// 加载图片
|
|
questionDto.LoadQuestionImage(v2.QuestionImage)
|
|
|
|
// 加载答案
|
|
questionDto.LoadQuestionAnswer(v2)
|
|
|
|
questionDtoList[i2] = questionDto
|
|
}
|
|
|
|
g.Question = append(g.Question, questionDtoList)
|
|
}
|
|
|
|
return g, nil
|
|
}
|
|
|
|
// GetShareQuestionQaForTypeThree 获取题库数据-多轮固定题型模式
|
|
func (r *QuestionQaService) GetShareQuestionQaForTypeThree(questionQa *model.QuestionQa) ([]*dto.ShareDtoForThree, error) {
|
|
// 初始化返回值
|
|
var g []*dto.ShareDtoForThree
|
|
|
|
if questionQa.QaType != 3 {
|
|
return g, errors.New("题库类型错误")
|
|
}
|
|
|
|
questionQaItemDao := dao.QuestionQaItemDao{}
|
|
|
|
// 题目数据-必备选中
|
|
maps := make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
maps["is_must_select"] = 1
|
|
mustQuestions, err := questionQaItemDao.GetQuestionQaItemWhereList(maps)
|
|
|
|
// 题目数据-未比被选中
|
|
maps = make(map[string]interface{})
|
|
maps["qa_id"] = questionQa.QaId
|
|
maps["is_must_select"] = 0
|
|
notMustQuestions, err := questionQaItemDao.GetQuestionQaItemWhereListRand(maps)
|
|
|
|
// json转结构体-飞花令题目数量规则
|
|
var tokenQuestionContents []tokenQuestionContent
|
|
err = json.Unmarshal([]byte(questionQa.TokenQuestionContent), &tokenQuestionContents)
|
|
if err != nil {
|
|
return g, errors.New(err.Error())
|
|
}
|
|
|
|
// 获取题库飞花令数据-列表
|
|
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{
|
|
Single: nil,
|
|
Multiple: nil,
|
|
Judge: nil,
|
|
Qa: nil,
|
|
}
|
|
|
|
// 套题规则 [{"question_type":1,"quantity":10},{"question_type":2,"quantity":0},{"question_type":3,"quantity":0},{"question_type":4,"quantity":0}]
|
|
for _, v2 := range tokenQuestionContents {
|
|
if v2.Quantity == 0 {
|
|
continue
|
|
}
|
|
|
|
shareDtoForTwo := &dto.ShareDtoForTwo{}
|
|
|
|
// 处理对应飞花令数据
|
|
for _, item := range baseTokenItems {
|
|
if len(shareDtoForTwo.BaseTokenItem) < *questionQa.TokenNum {
|
|
questionDto := dto.GetBaseTokenItemDto(item)
|
|
shareDtoForTwo.BaseTokenItem = append(shareDtoForTwo.BaseTokenItem, questionDto)
|
|
}
|
|
}
|
|
|
|
// 飞花令数量
|
|
for i3 := 0; i3 < *questionQa.TokenNum; i3++ {
|
|
// 题目数据
|
|
var questions []*model.Question
|
|
|
|
// 必选数据
|
|
for _, v3 := range mustQuestions {
|
|
// 判断此题目是否已被选中
|
|
if utils.IsInSlice(v3.QuestionId, isUseQuestionId) {
|
|
continue
|
|
}
|
|
|
|
// 类型相同,加入该组数据中
|
|
if v2.QuestionType == v3.Question.QuestionType {
|
|
// 当数量超出时,跳出
|
|
if len(questions) >= v2.Quantity {
|
|
continue
|
|
}
|
|
|
|
questions = append(questions, v3.Question)
|
|
|
|
// 标记已被使用
|
|
isUseQuestionId = append(isUseQuestionId, v3.QuestionId)
|
|
}
|
|
}
|
|
|
|
// 题目数据-剩余随机数量
|
|
remainingQuantity := v2.Quantity - len(questions)
|
|
if remainingQuantity > 0 {
|
|
// 非必选数据
|
|
for _, v3 := range notMustQuestions {
|
|
// 判断此题目是否已被选中
|
|
if utils.IsInSlice(v3.QuestionId, isUseQuestionId) {
|
|
continue
|
|
}
|
|
|
|
// 类型相同,加入该组数据中
|
|
if v2.QuestionType == v3.Question.QuestionType {
|
|
// 当数量超出时,跳出
|
|
if len(questions) >= v2.Quantity {
|
|
continue
|
|
}
|
|
|
|
questions = append(questions, v3.Question)
|
|
|
|
// 标记已被使用
|
|
isUseQuestionId = append(isUseQuestionId, v3.QuestionId)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理返回值
|
|
var questionDtoList []*dto.QuestionDto
|
|
|
|
// 处理数据
|
|
for _, v3 := range questions {
|
|
// 处理返回值
|
|
questionDto := dto.GetShareQuestionDto(v3)
|
|
|
|
// 加载选项
|
|
questionDto.LoadQuestionOptionSimplify(v3.QuestionOption)
|
|
|
|
// 加载图片
|
|
questionDto.LoadQuestionImage(v3.QuestionImage)
|
|
|
|
// 加载答案
|
|
questionDto.LoadQuestionAnswer(v3)
|
|
|
|
questionDtoList = append(questionDtoList, questionDto)
|
|
}
|
|
|
|
shareDtoForTwo.Question = append(shareDtoForTwo.Question, questionDtoList)
|
|
}
|
|
|
|
// 填入对应类别
|
|
if v2.QuestionType == 1 {
|
|
shareDtoForThree.Single = shareDtoForTwo
|
|
} else if v2.QuestionType == 2 {
|
|
shareDtoForThree.Multiple = shareDtoForTwo
|
|
} else if v2.QuestionType == 4 {
|
|
shareDtoForThree.Judge = shareDtoForTwo
|
|
} else if v2.QuestionType == 3 {
|
|
shareDtoForThree.Qa = shareDtoForTwo
|
|
} else {
|
|
return g, errors.New("内部错误")
|
|
}
|
|
}
|
|
|
|
// 添加如总数据
|
|
g = append(g, shareDtoForThree)
|
|
}
|
|
|
|
return g, nil
|
|
}
|
|
|
|
// CheckQuestionQaItemRepeat 检测题目明细重复
|
|
func (r *QuestionQaService) CheckQuestionQaItemRepeat(items []*requests.QuestionQaItem, newItem *requests.QuestionQaItem) bool {
|
|
for _, item := range items {
|
|
// 检查必填项
|
|
if item.QuestionType == newItem.QuestionType &&
|
|
item.FirstLabelId == newItem.FirstLabelId {
|
|
|
|
// 如果所有字段相同(包括选填项),不能添加
|
|
if item.SecondLabelId == newItem.SecondLabelId &&
|
|
((item.Difficulty == nil && newItem.Difficulty == nil) ||
|
|
(item.Difficulty != nil && newItem.Difficulty != nil && *item.Difficulty == *newItem.Difficulty)) {
|
|
return false
|
|
}
|
|
|
|
// 如果新增项选填项为空,但已有项选填项不为空,则冲突
|
|
if newItem.SecondLabelId == "" && item.SecondLabelId != "" {
|
|
return false
|
|
}
|
|
|
|
// 如果新增项选填项不为空,但已有项选填项为空,则冲突
|
|
if newItem.SecondLabelId != "" && item.SecondLabelId == "" {
|
|
return false
|
|
}
|
|
|
|
// 如果新增项选填项为空,但已有项选填项不为空,则冲突
|
|
if newItem.Difficulty == nil && item.Difficulty != nil {
|
|
return false
|
|
}
|
|
|
|
// 如果新增项选填项不为空,但已有项选填项为空,则冲突
|
|
if newItem.Difficulty != nil && item.Difficulty == nil {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// CheckQuestionRelationQaQuantitySub 检测题目关联的题库数量是否充足-减去对应数量后
|
|
func (r *QuestionQaService) CheckQuestionRelationQaQuantitySub(questionId int64, num int) (bool, error) {
|
|
// 获取关联题库id
|
|
questionQaItemDao := dao.QuestionQaItemDao{}
|
|
questionQaItems, err := questionQaItemDao.GetQuestionQaItemListByQuestionIdDistinctQaId(questionId)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
questionQaDao := dao.QuestionQaDao{}
|
|
for _, item := range questionQaItems {
|
|
// 获取题库数据
|
|
questionQa, err := questionQaDao.GetQuestionQaById(item.QaId)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
// 获取明细数据
|
|
questionQaItems, err = questionQaItemDao.GetQuestionQaItemListByQaId(item.QaId)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if (len(questionQaItems) - num) < questionQa.QaQuantity {
|
|
return false, errors.New("操作后会导致关联题库:" + questionQa.QaName + " 题目数量不足")
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|