package service import ( "errors" "fmt" "gorm.io/gorm" "knowledge/api/dao" "knowledge/api/dto" "knowledge/api/model" "knowledge/api/requests" "knowledge/global" "knowledge/utils" "strconv" "strings" ) type QuestionService struct { } // AddQuestion 新增题目 func (r *QuestionService) AddQuestion(req requests.AddQuestion) (bool, error) { // 验证一级标签 firstLabelId, err := strconv.ParseInt(req.FirstLabelId, 10, 64) if err != nil { return false, err } labelDao := dao.LabelDao{} _, err = labelDao.GetLabelFirstById(firstLabelId) if err != nil { return false, err } // 验证二级标签 var secondLabelId int64 if req.SecondLabelId != "" { secondLabelId, err := strconv.ParseInt(req.SecondLabelId, 10, 64) if err != nil { return false, err } _, err = labelDao.GetLabelFirstById(secondLabelId) if err != nil { return false, err } } // 处理图片 var questionImage string if len(req.QuestionImage) > 0 { result := make([]string, len(req.QuestionImage)) for i, url := range req.QuestionImage { result[i] = utils.RemoveOssDomain(url) } questionImage = strings.Join(result, ",") } // 判断选项 if req.QuestionType == 1 || req.QuestionType == 2 { if len(req.QuestionOption) == 0 { return false, errors.New("请填入选项") } } // 验证重复 questionDao := dao.QuestionDao{} maps := make(map[string]interface{}) maps["question_name"] = req.QuestionName question, _ := questionDao.GetQuestion(maps) if question != nil { return false, errors.New("题目名称重复") } // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() // 新增题目 question = &model.Question{ QuestionName: req.QuestionName, QuestionType: req.QuestionType, QuestionStatus: req.QuestionStatus, QuestionSource: req.QuestionSource, QuestionImage: questionImage, QuestionAnswer: req.QuestionAnswer, QuestionAnalysis: req.QuestionAnalysis, Difficulty: req.Difficulty, FirstLabelId: &firstLabelId, SecondLabelId: nil, } if req.SecondLabelId != "" { question.SecondLabelId = &secondLabelId } question, err = questionDao.AddQuestion(tx, question) if err != nil { tx.Rollback() return false, errors.New("新增失败") } // 新增选项 questionOptionDao := dao.QuestionOptionDao{} for _, s := range req.QuestionOption { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: s, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("新增失败") } } // 处理题库数据 if req.QaId != "" { qaId, err := strconv.ParseInt(req.QaId, 10, 64) if err != nil { tx.Rollback() return false, err } // 新增题库明细 questionQaItemDao := dao.QuestionQaItemDao{} questionQaItem := &model.QuestionQaItem{ QaId: qaId, QuestionId: question.QuestionId, IsMustSelect: 0, } _, err = questionQaItemDao.AddQuestionQaItem(tx, questionQaItem) if err != nil { tx.Rollback() return false, err } } tx.Commit() return true, nil } // AddQuestionTest 新增题目 func (r *QuestionService) AddQuestionTest(req requests.AddQuestionTest) (bool, error) { // 验证一级标签 firstLabelId, err := strconv.ParseInt(req.FirstLabelId, 10, 64) if err != nil { return false, err } labelDao := dao.LabelDao{} _, err = labelDao.GetLabelFirstById(firstLabelId) if err != nil { return false, err } // 验证二级标签 var secondLabelId int64 if req.SecondLabelId != "" { secondLabelId, err = strconv.ParseInt(req.SecondLabelId, 10, 64) if err != nil { return false, err } _, err = labelDao.GetLabelFirstById(secondLabelId) if err != nil { return false, err } } // 处理图片 var questionImage string if req.QuestionImage != nil { questionImage = *req.QuestionImage if strings.HasSuffix(questionImage, "|") { questionImage = questionImage[:len(questionImage)-1] } if strings.HasSuffix(questionImage, "|") { questionImage = questionImage[:len(questionImage)-1] } questionImages := strings.Split(questionImage, "|") if len(questionImages) > 0 { result := make([]string, len(questionImages)) for i, url := range questionImages { result[i] = utils.RemoveOssDomain(url) } questionImage = strings.Join(result, ",") } } // 判断选项 if req.QuestionType == 1 || req.QuestionType == 2 { if req.Input1 == nil { return false, errors.New("请填入选项") } } // 验证重复 questionDao := dao.QuestionDao{} maps := make(map[string]interface{}) maps["question_name"] = req.QuestionName question, _ := questionDao.GetQuestion(maps) if question != nil { return false, errors.New("题目名称重复") } questionStatus, err := strconv.Atoi(req.QuestionStatus) if err != nil { return false, errors.New("题目状态错误") } difficulty, err := strconv.Atoi(req.Difficulty) if err != nil { return false, errors.New("题目难度错误") } // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() // 新增题目 question = &model.Question{ QuestionName: req.QuestionName, QuestionType: req.QuestionType, QuestionStatus: questionStatus, QuestionSource: 1, QuestionImage: questionImage, QuestionAnswer: req.QuestionAnswer, QuestionAnalysis: req.QuestionAnalysis, Difficulty: difficulty, FirstLabelId: &firstLabelId, SecondLabelId: nil, } if req.SecondLabelId != "" { question.SecondLabelId = &secondLabelId } question, err = questionDao.AddQuestion(tx, question) if err != nil { tx.Rollback() return false, errors.New("新增失败") } // 新增选项 questionOptionDao := dao.QuestionOptionDao{} if req.QuestionType == 1 || req.QuestionType == 2 { if req.Input1 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input1, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("新增失败") } } if req.Input2 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input2, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("新增失败") } } if req.Input3 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input3, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("新增失败") } } if req.Input4 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input4, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("新增失败") } } if req.Input5 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input5, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("新增失败") } } } tx.Commit() return true, nil } // PutQuestion 修改题目 func (r *QuestionService) PutQuestion(questionId int64, req requests.PutQuestion) (bool, error) { questionDao := dao.QuestionDao{} question, err := questionDao.GetQuestionById(questionId) if err != nil { return false, errors.New("题目不存在") } // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() questionData := make(map[string]interface{}) // 题目名称 if req.QuestionName != question.QuestionName { questionData["question_name"] = req.QuestionName } // 题目类型 if req.QuestionType != question.QuestionType { questionData["question_type"] = req.QuestionType } // 状态 if req.QuestionStatus != question.QuestionStatus { questionData["question_status"] = req.QuestionStatus } // 答案 if req.QuestionAnswer != question.QuestionAnswer { questionData["question_answer"] = req.QuestionAnswer } // 解析 if req.QuestionAnalysis != question.QuestionAnalysis { questionData["question_analysis"] = req.QuestionAnalysis } // 难度 if req.Difficulty != question.Difficulty { questionData["difficulty"] = req.Difficulty } // 验证一级标签 firstLabelId, err := strconv.ParseInt(req.FirstLabelId, 10, 64) if err != nil { return false, err } if &firstLabelId != question.FirstLabelId { labelDao := dao.LabelDao{} _, err = labelDao.GetLabelFirstById(firstLabelId) if err != nil { return false, err } questionData["first_label_id"] = firstLabelId } // 验证二级标签 if req.SecondLabelId == "" { if question.SecondLabelId != nil { questionData["second_label_id"] = gorm.Expr("NULL") } } else { // 验证二级标签 if req.SecondLabelId != "" { secondLabelId, err := strconv.ParseInt(req.SecondLabelId, 10, 64) if err != nil { return false, err } if &firstLabelId != question.FirstLabelId { labelDao := dao.LabelDao{} _, err = labelDao.GetLabelFirstById(secondLabelId) if err != nil { return false, err } questionData["first_label_id"] = firstLabelId } } } // 图片 if len(req.QuestionImage) > 0 { result := make([]string, len(req.QuestionImage)) for i, url := range req.QuestionImage { result[i] = utils.RemoveOssDomain(url) } questionData["question_image"] = strings.Join(result, ",") } // 验证重复 if req.QuestionName != question.QuestionName { maps := make(map[string]interface{}) maps["question_name"] = req.QuestionName res, _ := questionDao.GetQuestion(maps) if res != nil { tx.Rollback() return false, errors.New("题目名称重复") } } // 删除所有选项 if question.QuestionType == 1 || question.QuestionType == 2 { questionOptionDao := dao.QuestionOptionDao{} err = questionOptionDao.DeleteQuestionOptionByQuestionId(tx, question.QuestionId) if err != nil { tx.Rollback() return false, errors.New(err.Error()) } } if req.QuestionType == 1 || req.QuestionType == 2 { // 新增选项 questionOptionDao := dao.QuestionOptionDao{} for _, s := range req.QuestionOption { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: s, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("修改失败") } } } err = questionDao.EditQuestionById(tx, question.QuestionId, questionData) if err != nil { tx.Rollback() return false, errors.New(err.Error()) } tx.Commit() return true, nil } // PutQuestionTest 修改题目 func (r *QuestionService) PutQuestionTest(questionId int64, req requests.PutQuestionTest) (bool, error) { questionDao := dao.QuestionDao{} question, err := questionDao.GetQuestionById(questionId) if err != nil { return false, errors.New("题目不存在") } // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() fmt.Println(r) } }() questionData := make(map[string]interface{}) // 题目名称 if req.QuestionName != question.QuestionName { questionData["question_name"] = req.QuestionName } // 题目类型 if req.QuestionType != "" { questionType, err := strconv.Atoi(req.QuestionType) if err != nil { tx.Rollback() return false, errors.New("题目类型错误") } if questionType != question.QuestionType { questionData["question_type"] = req.QuestionType } } // 状态 if req.QuestionStatus != "" { questionStatus, err := strconv.Atoi(req.QuestionStatus) if err != nil { tx.Rollback() return false, errors.New("题目状态错误") } if questionStatus != question.QuestionStatus { questionData["question_status"] = req.QuestionStatus } } // 答案 if req.QuestionAnswer != question.QuestionAnswer { questionData["question_answer"] = req.QuestionAnswer } // 解析 if req.QuestionAnalysis != question.QuestionAnalysis { questionData["question_analysis"] = req.QuestionAnalysis } // 难度 if req.Difficulty != "" { difficulty, err := strconv.Atoi(req.Difficulty) if err != nil { tx.Rollback() return false, errors.New("题目难度错误") } if difficulty != question.Difficulty { questionData["difficulty"] = req.Difficulty } } // 验证一级标签 firstLabelId, err := strconv.ParseInt(req.FirstLabelId, 10, 64) if err != nil { tx.Rollback() return false, err } if &firstLabelId != question.FirstLabelId { labelDao := dao.LabelDao{} _, err = labelDao.GetLabelFirstById(firstLabelId) if err != nil { tx.Rollback() return false, err } questionData["first_label_id"] = firstLabelId } // 验证二级标签 if req.SecondLabelId == "" { if question.SecondLabelId != nil { questionData["second_label_id"] = gorm.Expr("NULL") } } else { // 验证二级标签 if req.SecondLabelId != "" { secondLabelId, err := strconv.ParseInt(req.SecondLabelId, 10, 64) if err != nil { tx.Rollback() return false, err } if &secondLabelId != question.SecondLabelId { labelDao := dao.LabelDao{} _, err := labelDao.GetLabelFirstById(secondLabelId) if err != nil { tx.Rollback() return false, err } questionData["second_label_id"] = secondLabelId } } } // 图片 if req.QuestionImage != nil { questionImage := *req.QuestionImage if strings.HasSuffix(questionImage, "|") { questionImage = questionImage[:len(questionImage)-1] } if strings.HasSuffix(questionImage, ",") { questionImage = questionImage[:len(questionImage)-1] } questionImages := strings.Split(questionImage, "|") if len(questionImages) > 0 { result := make([]string, len(questionImages)) for i, url := range questionImages { result[i] = utils.RemoveOssDomain(url) } questionImage = strings.Join(result, ",") if questionImage != question.QuestionImage { questionData["question_image"] = questionImage } } } // 验证重复 if req.QuestionName != question.QuestionName { maps := make(map[string]interface{}) maps["question_name"] = req.QuestionName res, _ := questionDao.GetQuestion(maps) if res != nil { tx.Rollback() return false, errors.New("题目名称重复") } } // 删除所有选项 if question.QuestionType == 1 || question.QuestionType == 2 { questionOptionDao := dao.QuestionOptionDao{} err = questionOptionDao.DeleteQuestionOptionByQuestionId(tx, question.QuestionId) if err != nil { tx.Rollback() return false, errors.New(err.Error()) } } if req.QuestionType == "1" || req.QuestionType == "2" { // 新增选项 questionOptionDao := dao.QuestionOptionDao{} if req.Input1 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input1, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("修改失败") } } if req.Input2 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input2, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("修改失败") } } if req.Input3 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input3, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("修改失败") } } if req.Input4 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input4, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("修改失败") } } if req.Input5 != nil { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: *req.Input5, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() return false, errors.New("修改失败") } } } err = questionDao.EditQuestionById(tx, question.QuestionId, questionData) if err != nil { tx.Rollback() return false, errors.New(err.Error()) } tx.Commit() return true, nil } // DeleteQuestion 删除题目 func (r *QuestionService) DeleteQuestion(req requests.DeleteQuestion) (bool, error) { questionDao := dao.QuestionDao{} questionOptionDao := dao.QuestionOptionDao{} // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() for _, questionId := range req.QuestionId { // 将字符串转换为int64类型 questionId, err := strconv.ParseInt(questionId, 10, 64) if err != nil { tx.Rollback() return false, errors.New("删除失败") } _, err = questionDao.GetQuestionById(questionId) if err != nil { tx.Rollback() return false, errors.New("题目不存在") } // 删除选项 err = questionOptionDao.DeleteQuestionOptionByQuestionId(tx, questionId) if err != nil { tx.Rollback() return false, errors.New(err.Error()) } err = questionDao.DeleteQuestionById(tx, questionId) if err != nil { tx.Rollback() return false, errors.New("删除失败") } } tx.Commit() return true, nil } // GetQuestion 获取题目详情 func (r *QuestionService) GetQuestion(questionId int64) (g *dto.QuestionDto, err error) { questionDao := dao.QuestionDao{} question, err := questionDao.GetQuestionPreloadById(questionId) if err != nil { return nil, errors.New("题目不存在") } if question.QuestionStatus == 2 { return nil, errors.New("题目已禁用") } if question.IsDelete == 1 { return nil, errors.New("题目已删除") } // 处理返回值 g = dto.GetQuestionDto(question) // 加载一级标签 g.LoadFirstLabel(question.FirstLabel) // 加载二级标签 g.LoadSecondLabel(question.SecondLabel) // 加载选项 g.LoadQuestionOption(question.QuestionOption) return g, nil }