knowledge-api/api/service/QuestionQa.go
2024-07-02 17:37:50 +08:00

504 lines
12 KiB
Go

package service
import (
"errors"
"fmt"
"github.com/goccy/go-json"
"knowledge/api/dao"
"knowledge/api/dto"
"knowledge/api/model"
"knowledge/api/requests"
"knowledge/global"
"knowledge/utils"
"strconv"
"time"
)
type QuestionQaService struct {
}
// 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("过期时间需大于当前时间")
}
// 处理明细选题规则
itemContent, _ := json.Marshal(req.Item)
// 开始事务
tx := global.Db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 新增题目
questionQa := &model.QuestionQa{
QaName: req.QaName,
QaQuantity: req.QaQuantity,
QaStatus: 1,
QaRuleContent: req.QaRuleContent,
QaDisplayType: req.QaDisplayType,
QaExpireTime: model.LocalTime(qaExpireTime),
QaPassword: req.QaPassword,
OpenNumber: 0,
Image: req.Image,
ItemContent: string(itemContent),
}
questionQaDao := dao.QuestionQaDao{}
questionQa, err = questionQaDao.AddQuestionQa(tx, questionQa)
if err != nil {
tx.Rollback()
return false, errors.New("新增失败")
}
// 生成分享链接
qaShareId := utils.HashString(fmt.Sprintf("%d", questionQa.QaId))
if err != nil {
tx.Rollback()
return false, err
}
questionQaData := make(map[string]interface{})
questionQaData["qa_share_id"] = qaShareId
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
if err != nil {
tx.Rollback()
return false, errors.New("新增失败")
}
// 新增问答题库题目列表
questionDao := dao.QuestionDao{}
questionQaItemDao := dao.QuestionQaItemDao{}
for _, item := range req.Item {
// 验证一级标签
firstLabelId, err := strconv.ParseInt(item.FirstLabelId, 10, 64)
if err != nil {
tx.Rollback()
return false, err
}
labelDao := dao.LabelDao{}
_, err = labelDao.GetLabelFirstById(firstLabelId)
if err != nil {
tx.Rollback()
return false, err
}
// 验证二级标签
if item.SecondLabelId != "" {
secondLabelId, err := strconv.ParseInt(item.SecondLabelId, 10, 64)
if err != nil {
tx.Rollback()
return false, err
}
_, err = labelDao.GetLabelFirstById(secondLabelId)
if err != nil {
tx.Rollback()
return false, err
}
}
// 验证数量
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
}
total, err := questionDao.GetQuestionCount(maps)
if err != nil {
tx.Rollback()
return false, err
}
if total < int64(item.Quantity) {
tx.Rollback()
return false, errors.New("选题超出数量")
}
// 获取随机明细题目
questions, err := questionDao.GetQuestionListRand(maps, item.Quantity*3)
if err != nil {
tx.Rollback()
return false, err
}
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("新增失败")
}
}
}
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("过期时间需大于当前时间")
}
// 分享密码
if req.QaPassword != questionQa.QaPassword {
questionQaData["qa_password"] = req.QaPassword
}
// 背景图
image := utils.RemoveOssDomain(req.Image)
if image != questionQa.Image {
questionQaData["image"] = image
}
// 处理明细选题规则
itemContent, _ := json.Marshal(req.Item)
if string(itemContent) != questionQa.ItemContent {
questionQaData["item_content"] = string(itemContent)
}
// 题目数量
if req.QaQuantity != questionQa.QaQuantity {
if req.Action == 1 {
tx.Rollback()
return false, errors.New("您修改了题目数量,无法正常修改该题库,请重新生成")
}
questionQaData["qa_quantity"] = req.QaQuantity
}
// 处理题库明细-需重新生成时才会检测明细
if req.Action == 2 {
// 删除所有明细
questionQaItemDao := dao.QuestionQaItemDao{}
err := questionQaItemDao.DeleteQuestionQaItemByQaId(tx, questionQa.QaId)
if err != nil {
tx.Rollback()
return false, err
}
for _, item := range req.Item {
// 验证一级标签
firstLabelId, err := strconv.ParseInt(item.FirstLabelId, 10, 64)
if err != nil {
tx.Rollback()
return false, err
}
labelDao := dao.LabelDao{}
_, err = labelDao.GetLabelFirstById(firstLabelId)
if err != nil {
tx.Rollback()
return false, err
}
// 验证二级标签
if item.SecondLabelId != "" {
secondLabelId, err := strconv.ParseInt(item.SecondLabelId, 10, 64)
if err != nil {
tx.Rollback()
return false, err
}
_, err = labelDao.GetLabelFirstById(secondLabelId)
if err != nil {
tx.Rollback()
return false, err
}
}
// 验证数量
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
}
total, err := questionDao.GetQuestionCount(maps)
if err != nil {
tx.Rollback()
return false, err
}
if total < int64(item.Quantity) {
tx.Rollback()
return false, errors.New("选题超出数量")
}
// 获取随机明细题目
questions, err := questionDao.GetQuestionListRand(maps, req.QaQuantity*3)
if err != nil {
tx.Rollback()
return false, err
}
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 len(questionQaData) > 0 {
err = questionQaDao.EditQuestionQaById(tx, questionQa.QaId, questionQaData)
if err != nil {
tx.Rollback()
return false, errors.New(err.Error())
}
}
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
}
// GetQuestionQa 获取问答题库详情
func (r *QuestionQaService) GetQuestionQa(qaId int64) (g *dto.QuestionQaDto, err error) {
questionQaDao := dao.QuestionQaDao{}
questionQa, err := questionQaDao.GetQuestionQaById(qaId)
if err != nil {
return nil, errors.New("题库不存在")
}
if questionQa.QaStatus == 2 {
return nil, errors.New("题库已失效")
}
// 处理返回值
g = dto.GetQuestionQaDto(questionQa)
// 加载明细选题规则
g = g.LoadItemContent(questionQa.ItemContent)
return g, nil
}