diff --git a/api/controller/BaseToken.go b/api/controller/BaseToken.go new file mode 100644 index 0000000..b448ff8 --- /dev/null +++ b/api/controller/BaseToken.go @@ -0,0 +1,231 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "knowledge/api/dao" + "knowledge/api/dto" + "knowledge/api/model" + "knowledge/api/requests" + "knowledge/api/responses" + "knowledge/global" + "knowledge/utils" + "strconv" +) + +type BaseToken struct{} + +// GetTokenPage 获取列表-分页 +func (r *BaseToken) GetTokenPage(c *gin.Context) { + baseTokenRequest := requests.BaseTokenRequest{} + req := baseTokenRequest.GetTokenPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + baseTokenDao := dao.BaseTokenDao{} + baseToken, total, err := baseTokenDao.GetBaseTokenPageSearch(req, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + GetQuestionPageResponses := dto.GetBaseTokenListDto(baseToken) + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = GetQuestionPageResponses + responses.OkWithData(result, c) +} + +// GetTokenList 获取列表 +func (r *BaseToken) GetTokenList(c *gin.Context) { + baseTokenRequest := requests.BaseTokenRequest{} + req := baseTokenRequest.GetTokenList + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + baseTokenDao := dao.BaseTokenDao{} + baseToken, err := baseTokenDao.GetBaseTokenListSearch(req) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetBaseTokenListDto(baseToken) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + responses.OkWithData(g, c) +} + +// AddBaseToken 新增 +func (r *BaseToken) AddBaseToken(c *gin.Context) { + baseTokenRequest := requests.BaseTokenRequest{} + req := baseTokenRequest.AddBaseToken + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + // 新增飞花令 + baseTokenDao := dao.BaseTokenDao{} + baseToken := &model.BaseToken{ + TokenName: req.TokenName, + } + baseToken, err := baseTokenDao.AddBaseToken(tx, baseToken) + if err != nil { + tx.Rollback() + responses.FailWithMessage("新增失败", c) + return + } + + // 新增飞花令明细 + baseTokenItemDao := dao.BaseTokenItemDao{} + for _, item := range req.BaseTokenItem { + baseTokenItem := &model.BaseTokenItem{ + TokenId: baseToken.TokenId, + ItemName: item.ItemName, + ItemImage: utils.RemoveOssDomain(item.ItemImage), + ItemSort: item.ItemSort, + } + baseTokenItem, err := baseTokenItemDao.AddBaseTokenItem(tx, baseTokenItem) + if err != nil { + tx.Rollback() + responses.FailWithMessage("新增失败", c) + return + } + } + + tx.Commit() + responses.Ok(c) +} + +// PutBaseToken 修改 +func (r *BaseToken) PutBaseToken(c *gin.Context) { + baseTokenRequest := requests.BaseTokenRequest{} + req := baseTokenRequest.PutBaseToken + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + id := c.Param("token_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + tokenId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取详情 + baseTokenDao := dao.BaseTokenDao{} + baseToken, err := baseTokenDao.GetBaseTokenById(tokenId) + if err != nil { + responses.FailWithMessage("数据不存在", c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + baseTokenData := make(map[string]interface{}) + if req.TokenName != baseToken.TokenName { + baseTokenData["token_name"] = req.TokenName + } + + if len(baseTokenData) > 0 { + err := baseTokenDao.EditBaseTokenById(tx, tokenId, baseTokenData) + if err != nil { + tx.Rollback() + responses.FailWithMessage("修改失败", c) + return + } + } + + // 删除明细 + baseTokenItemDao := dao.BaseTokenItemDao{} + err = baseTokenItemDao.DeleteBaseTokenItemByTokenId(tx, baseToken.TokenId) + if err != nil { + tx.Rollback() + responses.FailWithMessage("修改失败", c) + return + } + + // 新增飞花令明细 + for _, item := range req.BaseTokenItem { + baseTokenItem := &model.BaseTokenItem{ + TokenId: baseToken.TokenId, + ItemName: item.ItemName, + ItemImage: utils.RemoveOssDomain(item.ItemImage), + ItemSort: item.ItemSort, + } + baseTokenItem, err := baseTokenItemDao.AddBaseTokenItem(tx, baseTokenItem) + if err != nil { + tx.Rollback() + responses.FailWithMessage("修改失败", c) + return + } + } + + tx.Commit() + responses.Ok(c) +} diff --git a/api/controller/BaseTokenItem.go b/api/controller/BaseTokenItem.go new file mode 100644 index 0000000..ec210ea --- /dev/null +++ b/api/controller/BaseTokenItem.go @@ -0,0 +1,86 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "knowledge/api/dao" + "knowledge/api/dto" + "knowledge/api/requests" + "knowledge/api/responses" + "knowledge/global" + "knowledge/utils" +) + +type BaseTokenItem struct{} + +// GetBaseTokenItemPage 获取列表-分页 +func (r *BaseTokenItem) GetBaseTokenItemPage(c *gin.Context) { + baseTokenItemRequest := requests.BaseTokenItemRequest{} + req := baseTokenItemRequest.GetBaseTokenItemPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + baseTokenItemDao := dao.BaseTokenItemDao{} + baseTokenItem, total, err := baseTokenItemDao.GetBaseTokenItemPageSearch(req, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetBaseTokenItemListDto(baseTokenItem) + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetBaseTokenItemList 获取列表 +func (r *BaseTokenItem) GetBaseTokenItemList(c *gin.Context) { + baseTokenItemRequest := requests.BaseTokenItemRequest{} + req := baseTokenItemRequest.GetBaseTokenItemList + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + baseTokenItemDao := dao.BaseTokenItemDao{} + baseTokenItem, err := baseTokenItemDao.GetBaseTokenItemListSearch(req) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetBaseTokenItemListDto(baseTokenItem) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + responses.OkWithData(g, c) +} diff --git a/api/controller/base.go b/api/controller/base.go index be8f066..c9e540c 100644 --- a/api/controller/base.go +++ b/api/controller/base.go @@ -11,4 +11,6 @@ type Api struct { Label // 标签 Static // 统计 Share // 分享 + BaseToken // 基础数据-飞花令 + BaseTokenItem // 基础数据-飞花令-明细 } diff --git a/api/controller/questionQa.go b/api/controller/questionQa.go index 9e51798..b305d26 100644 --- a/api/controller/questionQa.go +++ b/api/controller/questionQa.go @@ -75,13 +75,22 @@ func (r *QuestionQa) AddQuestionQa(c *gin.Context) { } // 参数验证 - for _, item := range req.Item { + for _, item := range req.BaseTokenItem { if err := global.Validate.Struct(item); err != nil { responses.FailWithMessage(utils.Translate(err), c) return } } + if req.BaseTokenItem != nil && req.QaDisplayType == 2 { + for _, item := range req.BaseTokenItem { + if err := global.Validate.Struct(item); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + } + } + // 业务处理 questionQaService := service.QuestionQaService{} _, err := questionQaService.AddQuestionQa(req) @@ -109,13 +118,22 @@ func (r *QuestionQa) PutQuestionQa(c *gin.Context) { } // 参数验证 - for _, item := range req.Item { + for _, item := range req.QuestionQaItem { if err := global.Validate.Struct(item); err != nil { responses.FailWithMessage(utils.Translate(err), c) return } } + if req.BaseTokenItem != nil && req.QaDisplayType == 2 { + for _, item := range req.BaseTokenItem { + if err := global.Validate.Struct(item); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + } + } + id := c.Param("qa_id") if id == "" { responses.FailWithMessage("缺少参数", c) @@ -272,13 +290,23 @@ func (r *QuestionQa) GetQuestionQa(c *gin.Context) { return } - // 业务处理 - questionQaService := service.QuestionQaService{} - getQuestionQaResponses, err := questionQaService.GetQuestionQa(qaId) + questionQaDao := dao.QuestionQaDao{} + questionQa, err := questionQaDao.GetQuestionQaById(qaId) if err != nil { - responses.FailWithMessage(err.Error(), c) + responses.FailWithMessage("题库不存在", c) return } - responses.OkWithData(getQuestionQaResponses, c) + if questionQa.QaStatus == 2 { + responses.FailWithMessage("题库已失效", c) + return + } + + // 处理返回值 + g := dto.GetQuestionQaDto(questionQa) + + // 加载明细选题规则 + g = g.LoadItemContent(questionQa.ItemContent) + + responses.OkWithData(g, c) } diff --git a/api/controller/share.go b/api/controller/share.go index 691daa8..4799782 100644 --- a/api/controller/share.go +++ b/api/controller/share.go @@ -2,11 +2,14 @@ package controller import ( "github.com/gin-gonic/gin" + "knowledge/api/dao" + "knowledge/api/dto" "knowledge/api/requests" "knowledge/api/responses" - "knowledge/api/service" "knowledge/global" "knowledge/utils" + "sort" + "time" ) type Share struct{} @@ -27,12 +30,100 @@ func (r *Share) GetShare(c *gin.Context) { } // 业务处理 - shareService := service.ShareService{} - getShareResponses, err := shareService.GetShare(req) - if err != nil { - responses.FailWithMessage(err.Error(), c) + questionQaDao := dao.QuestionQaDao{} + questionQaItemDao := dao.QuestionQaItemDao{} + questionDao := dao.QuestionDao{} + + // 获取题库数据 + maps := make(map[string]interface{}) + maps["qa_share_id"] = req.QaShareId + questionQa, err := questionQaDao.GetQuestionQa(maps) + if err != nil || questionQa == nil { + responses.FailWithMessage("题库不存在", c) return } - responses.OkWithData(getShareResponses, c) + if questionQa.QaStatus == 2 { + responses.FailWithMessage("题库已失效", c) + return + } + + if questionQa.QaPassword != req.QaPassword { + responses.FailWithMessage("密码错误", c) + return + } + + // 检测过期时间 + now := time.Now() + qaExpireTime := time.Time(questionQa.QaExpireTime) + if qaExpireTime.Before(now) { + responses.FailWithMessage("题库已失效", c) + return + } + + g := &dto.ShareDto{} + + // 加载题库数据 + g.QuestionQa = dto.GetQuestionQaDto(questionQa) + + // 题目数据-必备选中 + maps = make(map[string]interface{}) + maps["qa_id"] = questionQa.QaId + maps["is_must_select"] = 1 + questionQaItems, err := questionQaItemDao.GetQuestionQaItemList(maps) + if err == nil && len(questionQaItems) > 0 { + shareQuestionDtos := make([]*dto.ShareQuestionDto, len(questionQaItems)) + + for i, item := range questionQaItems { + // 获取题目数据 + question, err := questionDao.GetQuestionById(item.QuestionId) + if err != nil { + responses.FailWithMessage("题目错误", c) + return + } + + shareQuestionDto := dto.GetShareQuestionDto(question) + + shareQuestionDto.IsMustSelect = item.IsMustSelect + + // 将转换后的结构体添加到新切片中 + shareQuestionDtos[i] = shareQuestionDto + } + + g.Question = shareQuestionDtos + } + + // 题目数据-剩余随机数量 + 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.GetQuestionQaItemListRand(maps, remainingQuantity) + if err == nil && len(questionQaItems) > 0 { + for _, item := range questionQaItems { + // 获取题目数据 + question, err := questionDao.GetQuestionById(item.QuestionId) + if err != nil { + responses.FailWithMessage("题目错误", c) + return + } + + shareQuestionDto := dto.GetShareQuestionDto(question) + + shareQuestionDto.IsMustSelect = item.IsMustSelect + + // 将转换后的结构体添加到新切片中 + g.Question = append(g.Question, shareQuestionDto) + } + } + } + + // 按照难度重新排序题目顺序 + sort.SliceStable(g.Question, func(i, j int) bool { + return g.Question[i].Difficulty < g.Question[j].Difficulty + }) + + responses.OkWithData(g, c) } diff --git a/api/dao/BaseToken.go b/api/dao/BaseToken.go new file mode 100644 index 0000000..3c01b67 --- /dev/null +++ b/api/dao/BaseToken.go @@ -0,0 +1,156 @@ +package dao + +import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" + "knowledge/api/model" + "knowledge/api/requests" + "knowledge/global" +) + +type BaseTokenDao struct { +} + +// GetBaseTokenById 获取数据-id +func (r *BaseTokenDao) GetBaseTokenById(tokenId int64) (m *model.BaseToken, err error) { + err = global.Db.First(&m, tokenId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseTokenPreloadById 获取数据-加载全部关联-id +func (r *BaseTokenDao) GetBaseTokenPreloadById(tokenId int64) (m *model.BaseToken, err error) { + err = global.Db.Preload(clause.Associations).First(&m, tokenId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// DeleteBaseToken 删除 +func (r *BaseTokenDao) DeleteBaseToken(tx *gorm.DB, maps interface{}) error { + err := tx.Where(maps).Delete(&model.BaseToken{}).Error + if err != nil { + return err + } + return nil +} + +// DeleteBaseTokenById 删除-id +func (r *BaseTokenDao) DeleteBaseTokenById(tx *gorm.DB, tokenId int64) error { + if err := tx.Delete(&model.BaseToken{}, tokenId).Error; err != nil { + return err + } + return nil +} + +// EditBaseToken 修改 +func (r *BaseTokenDao) EditBaseToken(tx *gorm.DB, maps interface{}, data interface{}) error { + err := tx.Model(&model.BaseToken{}).Where(maps).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// EditBaseTokenById 修改-id +func (r *BaseTokenDao) EditBaseTokenById(tx *gorm.DB, tokenId int64, data interface{}) error { + err := tx.Model(&model.BaseToken{}).Where("token_id = ?", tokenId).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// GetBaseTokenList 获取列表 +func (r *BaseTokenDao) GetBaseTokenList(maps interface{}) (m []*model.BaseToken, err error) { + err = global.Db.Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseTokenCount 获取数量 +func (r *BaseTokenDao) GetBaseTokenCount(maps interface{}) (total int64, err error) { + err = global.Db.Model(&model.BaseToken{}).Where(maps).Count(&total).Error + if err != nil { + return 0, err + } + return total, nil +} + +// GetBaseTokenListRand 获取列表-随机 +func (r *BaseTokenDao) GetBaseTokenListRand(maps interface{}, limit int) (m []*model.BaseToken, err error) { + err = global.Db.Where(maps).Order("rand()").Limit(limit).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// AddBaseToken 新增 +func (r *BaseTokenDao) AddBaseToken(tx *gorm.DB, model *model.BaseToken) (*model.BaseToken, error) { + if err := tx.Create(model).Error; err != nil { + return nil, err + } + return model, nil +} + +// GetBaseToken 获取 +func (r *BaseTokenDao) GetBaseToken(maps interface{}) (m *model.BaseToken, err error) { + err = global.Db.Where(maps).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseTokenPageSearch 获取列表-分页 +func (r *BaseTokenDao) GetBaseTokenPageSearch(req requests.GetTokenPage, page, pageSize int) (m []*model.BaseToken, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.BaseToken{}) + + // 排序 + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetBaseTokenListSearch 获取列表 +func (r *BaseTokenDao) GetBaseTokenListSearch(req requests.GetTokenList) (m []*model.BaseToken, err error) { + // 构建查询条件 + query := global.Db.Model(&model.BaseToken{}) + + // 主键id + if req.TokenId != "" { + query = query.Where("token_id = ?", req.TokenId) + } + + // 名称 + if req.TokenName != "" { + query = query.Where("token_name LIKE ?", "%"+req.TokenName+"%") + } + + // 排序 + query = query.Order("created_at desc") + + err = query.Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dao/BaseTokenItem.go b/api/dao/BaseTokenItem.go new file mode 100644 index 0000000..d05782b --- /dev/null +++ b/api/dao/BaseTokenItem.go @@ -0,0 +1,176 @@ +package dao + +import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" + "knowledge/api/model" + "knowledge/api/requests" + "knowledge/global" +) + +type BaseTokenItemDao struct { +} + +// GetBaseTokenItemById 获取数据-id +func (r *BaseTokenItemDao) GetBaseTokenItemById(ItemId int64) (m *model.BaseTokenItem, err error) { + err = global.Db.First(&m, ItemId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseTokenItemPreloadById 获取数据-加载全部关联-id +func (r *BaseTokenItemDao) GetBaseTokenItemPreloadById(ItemId int64) (m *model.BaseTokenItem, err error) { + err = global.Db.Preload(clause.Associations).First(&m, ItemId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// DeleteBaseTokenItem 删除 +func (r *BaseTokenItemDao) DeleteBaseTokenItem(tx *gorm.DB, maps interface{}) error { + err := tx.Where(maps).Delete(&model.BaseTokenItem{}).Error + if err != nil { + return err + } + return nil +} + +// DeleteBaseTokenItemById 删除-id +func (r *BaseTokenItemDao) DeleteBaseTokenItemById(tx *gorm.DB, ItemId int64) error { + if err := tx.Delete(&model.BaseTokenItem{}, ItemId).Error; err != nil { + return err + } + return nil +} + +// DeleteBaseTokenItemByTokenId 删除-TokenId +func (r *BaseTokenItemDao) DeleteBaseTokenItemByTokenId(tx *gorm.DB, TokenId int64) error { + if err := tx.Where("token_id = ?", TokenId).Delete(&model.BaseTokenItem{}).Error; err != nil { + return err + } + return nil +} + +// EditBaseTokenItem 修改 +func (r *BaseTokenItemDao) EditBaseTokenItem(tx *gorm.DB, maps interface{}, data interface{}) error { + err := tx.Model(&model.BaseTokenItem{}).Where(maps).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// EditBaseTokenItemById 修改-id +func (r *BaseTokenItemDao) EditBaseTokenItemById(tx *gorm.DB, ItemId int64, data interface{}) error { + err := tx.Model(&model.BaseTokenItem{}).Where("item_id = ?", ItemId).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// GetBaseTokenItemList 获取列表 +func (r *BaseTokenItemDao) GetBaseTokenItemList(maps interface{}) (m []*model.BaseTokenItem, err error) { + err = global.Db.Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseTokenItemCount 获取数量 +func (r *BaseTokenItemDao) GetBaseTokenItemCount(maps interface{}) (total int64, err error) { + err = global.Db.Model(&model.BaseTokenItem{}).Where(maps).Count(&total).Error + if err != nil { + return 0, err + } + return total, nil +} + +// GetBaseTokenItemListRand 获取列表-随机 +func (r *BaseTokenItemDao) GetBaseTokenItemListRand(maps interface{}, limit int) (m []*model.BaseTokenItem, err error) { + err = global.Db.Where(maps).Order("rand()").Limit(limit).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// AddBaseTokenItem 新增 +func (r *BaseTokenItemDao) AddBaseTokenItem(tx *gorm.DB, model *model.BaseTokenItem) (*model.BaseTokenItem, error) { + if err := tx.Create(model).Error; err != nil { + return nil, err + } + return model, nil +} + +// GetBaseTokenItem 获取 +func (r *BaseTokenItemDao) GetBaseTokenItem(maps interface{}) (m *model.BaseTokenItem, err error) { + err = global.Db.Where(maps).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseTokenItemPageSearch 获取列表-分页 +func (r *BaseTokenItemDao) GetBaseTokenItemPageSearch(req requests.GetBaseTokenItemPage, page, pageSize int) (m []*model.BaseTokenItem, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.BaseTokenItem{}) + + // 飞花令id + if req.TokenId != "" { + query = query.Where("token_id = ?", req.TokenId) + } + + // 排序 + query = query.Order("item_sort desc") + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetBaseTokenItemListSearch 获取列表 +func (r *BaseTokenItemDao) GetBaseTokenItemListSearch(req requests.GetBaseTokenItemList) (m []*model.BaseTokenItem, err error) { + // 构建查询条件 + query := global.Db.Model(&model.BaseTokenItem{}) + + // 主键id + if req.ItemId != "" { + query = query.Where("item_id = ?", req.ItemId) + } + + // 飞花令id + if req.TokenId != "" { + query = query.Where("token_id = ?", req.TokenId) + } + + // 名称 + if req.ItemName != "" { + query = query.Where("item_name LIKE ?", "%"+req.ItemName+"%") + } + + // 排序 + query = query.Order("item_sort desc") + query = query.Order("created_at desc") + + err = query.Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dao/QuestionQaToken.go b/api/dao/QuestionQaToken.go new file mode 100644 index 0000000..121ecda --- /dev/null +++ b/api/dao/QuestionQaToken.go @@ -0,0 +1,108 @@ +package dao + +import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" + "knowledge/api/model" + "knowledge/global" +) + +type QuestionQaTokenDao struct { +} + +// GetQuestionQaTokenById 获取数据-id +func (r *QuestionQaTokenDao) GetQuestionQaTokenById(QaTokenId int64) (m *model.QuestionQaToken, err error) { + err = global.Db.First(&m, QaTokenId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetQuestionQaTokenPreloadById 获取数据-加载全部关联-id +func (r *QuestionQaTokenDao) GetQuestionQaTokenPreloadById(QaTokenId int64) (m *model.QuestionQaToken, err error) { + err = global.Db.Preload(clause.Associations).First(&m, QaTokenId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// DeleteQuestionQaToken 删除 +func (r *QuestionQaTokenDao) DeleteQuestionQaToken(tx *gorm.DB, maps interface{}) error { + err := tx.Where(maps).Delete(&model.QuestionQaToken{}).Error + if err != nil { + return err + } + return nil +} + +// DeleteQuestionQaTokenById 删除-id +func (r *QuestionQaTokenDao) DeleteQuestionQaTokenById(tx *gorm.DB, QaTokenId int64) error { + if err := tx.Delete(&model.QuestionQaToken{}, QaTokenId).Error; err != nil { + return err + } + return nil +} + +// EditQuestionQaToken 修改 +func (r *QuestionQaTokenDao) EditQuestionQaToken(tx *gorm.DB, maps interface{}, data interface{}) error { + err := tx.Model(&model.QuestionQaToken{}).Where(maps).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// EditQuestionQaTokenById 修改-id +func (r *QuestionQaTokenDao) EditQuestionQaTokenById(tx *gorm.DB, QaTokenId int64, data interface{}) error { + err := tx.Model(&model.QuestionQaToken{}).Where("qa_token_id = ?", QaTokenId).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// GetQuestionQaTokenList 获取列表 +func (r *QuestionQaTokenDao) GetQuestionQaTokenList(maps interface{}) (m []*model.QuestionQaToken, err error) { + err = global.Db.Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetQuestionQaTokenCount 获取数量 +func (r *QuestionQaTokenDao) GetQuestionQaTokenCount(maps interface{}) (total int64, err error) { + err = global.Db.Model(&model.QuestionQaToken{}).Where(maps).Count(&total).Error + if err != nil { + return 0, err + } + return total, nil +} + +// GetQuestionQaTokenListRand 获取列表-随机 +func (r *QuestionQaTokenDao) GetQuestionQaTokenListRand(maps interface{}, limit int) (m []*model.QuestionQaToken, err error) { + err = global.Db.Where(maps).Order("rand()").Limit(limit).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// AddQuestionQaToken 新增 +func (r *QuestionQaTokenDao) AddQuestionQaToken(tx *gorm.DB, model *model.QuestionQaToken) (*model.QuestionQaToken, error) { + if err := tx.Create(model).Error; err != nil { + return nil, err + } + return model, nil +} + +// GetQuestionQaToken 获取 +func (r *QuestionQaTokenDao) GetQuestionQaToken(maps interface{}) (m *model.QuestionQaToken, err error) { + err = global.Db.Where(maps).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dto/BaseToken.go b/api/dto/BaseToken.go new file mode 100644 index 0000000..6291939 --- /dev/null +++ b/api/dto/BaseToken.go @@ -0,0 +1,46 @@ +package dto + +import ( + "fmt" + "knowledge/api/model" +) + +// BaseTokenDto 基础数据-飞花令 +type BaseTokenDto struct { + TokenId string `json:"token_id"` // 主键id + TokenName string `json:"token_name"` // 名称 + CreatedAt model.LocalTime `json:"created_at"` // 创建时间 + UpdatedAt model.LocalTime `json:"updated_at"` // 修改时间 +} + +// GetBaseTokenDto 详情 +func GetBaseTokenDto(m *model.BaseToken) *BaseTokenDto { + return &BaseTokenDto{ + TokenId: fmt.Sprintf("%d", m.TokenId), + TokenName: m.TokenName, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, + } +} + +// GetBaseTokenListDto 列表 +func GetBaseTokenListDto(m []*model.BaseToken) []*BaseTokenDto { + // 处理返回值 + responses := make([]*BaseTokenDto, len(m)) + + if len(m) > 0 { + for i, v := range m { + response := &BaseTokenDto{ + TokenId: fmt.Sprintf("%d", v.TokenId), + TokenName: v.TokenName, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + + // 将转换后的结构体添加到新切片中 + responses[i] = response + } + } + + return responses +} diff --git a/api/dto/BaseTokenItem.go b/api/dto/BaseTokenItem.go new file mode 100644 index 0000000..e0c96c2 --- /dev/null +++ b/api/dto/BaseTokenItem.go @@ -0,0 +1,56 @@ +package dto + +import ( + "fmt" + "knowledge/api/model" + "knowledge/utils" +) + +// BaseTokenItemDto 基础数据-飞花令-列表 +type BaseTokenItemDto struct { + ItemId string `json:"item_id"` // 主键id + TokenId string `json:"token_id"` // 飞花令id + ItemName string `json:"item_name"` // 名称 + ItemImage string `json:"item_image"` // 图片地址 + ItemSort int `json:"item_sort"` // 排序(越大越靠前) + CreatedAt model.LocalTime `json:"created_at"` // 创建时间 + UpdatedAt model.LocalTime `json:"updated_at"` // 修改时间 +} + +// GetBaseTokenItemDto 详情 +func GetBaseTokenItemDto(m *model.BaseTokenItem) *BaseTokenItemDto { + return &BaseTokenItemDto{ + ItemId: fmt.Sprintf("%d", m.ItemId), + TokenId: fmt.Sprintf("%d", m.TokenId), + ItemName: m.ItemName, + ItemImage: utils.AddOssDomain(m.ItemImage), + ItemSort: m.ItemSort, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, + } +} + +// GetBaseTokenItemListDto 列表 +func GetBaseTokenItemListDto(m []*model.BaseTokenItem) []*BaseTokenItemDto { + // 处理返回值 + responses := make([]*BaseTokenItemDto, len(m)) + + if len(m) > 0 { + for i, v := range m { + response := &BaseTokenItemDto{ + ItemId: fmt.Sprintf("%d", v.ItemId), + TokenId: fmt.Sprintf("%d", v.TokenId), + ItemName: v.ItemName, + ItemImage: utils.AddOssDomain(v.ItemImage), + ItemSort: v.ItemSort, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + + // 将转换后的结构体添加到新切片中 + responses[i] = response + } + } + + return responses +} diff --git a/api/dto/Share.go b/api/dto/Share.go index a3fe72f..a776b57 100644 --- a/api/dto/Share.go +++ b/api/dto/Share.go @@ -16,11 +16,11 @@ type ShareQuestionDto struct { QuestionName string `json:"question_name"` // 题目名称 QuestionType int `json:"question_type"` // 题目类型(1:单选 2:多选 3:问答 4:判断) QuestionSource int `json:"question_source"` // 题目来源(1:本题库 2:外部数据) - QuestionImage []string `json:"question_image"` // 题目图片(逗号分隔) + QuestionImage []string `json:"question_image"` // 题目图片 QuestionAnswer string `json:"question_answer"` // 答案 QuestionAnalysis string `json:"question_analysis"` // 解析 Difficulty int `json:"difficulty"` // 难度(0:未知 1:低 2:中 3:高) - IsMustSelect int `json:"is_must_select"` + IsMustSelect int `json:"is_must_select"` // 是否必被选中 } // GetShareQuestionDto 分享题目详情 diff --git a/api/middlewares/auth.go b/api/middlewares/auth.go index 354f0e2..f51e01f 100644 --- a/api/middlewares/auth.go +++ b/api/middlewares/auth.go @@ -17,37 +17,52 @@ func Auth() gin.HandlerFunc { return } - // 获取用户数据 - adminUserDao := dao.AdminUserDao{} - adminUser, err := adminUserDao.GetAdminUserFirstById(userId) - if err != nil || adminUser == nil { - responses.FailWithMessage("用户数据错误", c) + // 获取客户端 + client := c.GetInt("Client") + if client == 0 || (client != 1 && client != 2) { + responses.FailWithMessage("token错误", c) c.Abort() return } - if adminUser.Status == 2 { - responses.FailWithMessage("用户审核中", c) - c.Abort() - return + // 前台 + if client == 1 { + } - if adminUser.Status == 3 { - responses.FailWithMessage("用户已删除或禁用", c) - c.Abort() - return - } + // 后台 + if client == 2 { + adminUserDao := dao.AdminUserDao{} + adminUser, err := adminUserDao.GetAdminUserFirstById(userId) + if err != nil || adminUser == nil { + responses.FailWithMessage("用户数据错误", c) + c.Abort() + return + } - if adminUser.IsDisabled == 1 { - responses.FailWithMessage("用户已禁用", c) - c.Abort() - return - } + if adminUser.Status == 2 { + responses.FailWithMessage("用户审核中", c) + c.Abort() + return + } - if adminUser.IsDeleted == 1 { - responses.FailWithMessage("用户已删除", c) - c.Abort() - return + if adminUser.Status == 3 { + responses.FailWithMessage("用户已删除或禁用", c) + c.Abort() + return + } + + if adminUser.IsDisabled == 1 { + responses.FailWithMessage("用户已禁用", c) + c.Abort() + return + } + + if adminUser.IsDeleted == 1 { + responses.FailWithMessage("用户已删除", c) + c.Abort() + return + } } c.Next() diff --git a/api/middlewares/jwt.go b/api/middlewares/jwt.go index 746e715..b412919 100644 --- a/api/middlewares/jwt.go +++ b/api/middlewares/jwt.go @@ -66,7 +66,8 @@ func Jwt() gin.HandlerFunc { return } - c.Set("UserId", userId) // 用户id + c.Set("UserId", userId) // 用户id + c.Set("Client", t.Client) // 客户端(1:前台 2:后台) c.Next() } } diff --git a/api/model/BaseToken.go b/api/model/BaseToken.go new file mode 100644 index 0000000..087c49d --- /dev/null +++ b/api/model/BaseToken.go @@ -0,0 +1,32 @@ +package model + +import ( + "gorm.io/gorm" + "knowledge/global" + "time" +) + +// BaseToken 基础数据-飞花令 +type BaseToken struct { + TokenId int64 `gorm:"column:token_id;type:bigint(19);primary_key;comment:主键id" json:"token_id"` + TokenName string `gorm:"column:token_name;type:varchar(100);comment:名称" json:"token_name"` + Model +} + +func (m *BaseToken) TableName() string { + return "kb_base_token" +} + +func (m *BaseToken) BeforeCreate(tx *gorm.DB) error { + if m.TokenId == 0 { + m.TokenId = global.Snowflake.Generate().Int64() + } + + m.CreatedAt = LocalTime(time.Now()) + tx.Statement.SetColumn("CreatedAt", m.CreatedAt) + + m.UpdatedAt = LocalTime(time.Now()) + tx.Statement.SetColumn("UpdatedAt", m.UpdatedAt) + + return nil +} diff --git a/api/model/BaseTokenItem.go b/api/model/BaseTokenItem.go new file mode 100644 index 0000000..3b4addf --- /dev/null +++ b/api/model/BaseTokenItem.go @@ -0,0 +1,35 @@ +package model + +import ( + "gorm.io/gorm" + "knowledge/global" + "time" +) + +// BaseTokenItem 基础数据-飞花令-列表 +type BaseTokenItem struct { + ItemId int64 `gorm:"column:item_id;type:bigint(19);primary_key;comment:主键id" json:"item_id"` + TokenId int64 `gorm:"column:token_id;type:bigint(19);comment:飞花令id;NOT NULL" json:"token_id"` + ItemName string `gorm:"column:item_name;type:varchar(100);comment:名称" json:"item_name"` + ItemImage string `gorm:"column:item_image;type:varchar(255);comment:图片地址" json:"item_image"` + ItemSort int `gorm:"column:item_sort;type:int(1);default:0;comment:排序(越大越靠前)" json:"item_sort"` + Model +} + +func (m *BaseTokenItem) TableName() string { + return "kb_base_token_item" +} + +func (m *BaseTokenItem) BeforeCreate(tx *gorm.DB) error { + if m.ItemId == 0 { + m.ItemId = global.Snowflake.Generate().Int64() + } + + m.CreatedAt = LocalTime(time.Now()) + tx.Statement.SetColumn("CreatedAt", m.CreatedAt) + + m.UpdatedAt = LocalTime(time.Now()) + tx.Statement.SetColumn("UpdatedAt", m.UpdatedAt) + + return nil +} diff --git a/api/model/QuestionQaToken.go b/api/model/QuestionQaToken.go new file mode 100644 index 0000000..600f022 --- /dev/null +++ b/api/model/QuestionQaToken.go @@ -0,0 +1,33 @@ +package model + +import ( + "gorm.io/gorm" + "knowledge/global" + "time" +) + +type QuestionQaToken struct { + QaTokenId int64 `gorm:"column:qa_token_id;type:bigint(19);primary_key;comment:主键id" json:"qa_token_id"` + QaId int64 `gorm:"column:qa_id;type:bigint(19);comment:知识问答id" json:"qa_id"` + TokenId int64 `gorm:"column:token_id;type:bigint(19);comment:飞花令id" json:"token_id"` + Sort int `gorm:"column:sort;type:tinyint(1);comment:排序(越大越靠前)" json:"sort"` + Model +} + +func (m *QuestionQaToken) TableName() string { + return "kb_question_qa_token" +} + +func (m *QuestionQaToken) BeforeCreate(tx *gorm.DB) error { + if m.QaTokenId == 0 { + m.QaTokenId = global.Snowflake.Generate().Int64() + } + + m.CreatedAt = LocalTime(time.Now()) + tx.Statement.SetColumn("CreatedAt", m.CreatedAt) + + m.UpdatedAt = LocalTime(time.Now()) + tx.Statement.SetColumn("UpdatedAt", m.UpdatedAt) + + return nil +} diff --git a/api/requests/BaseToken.go b/api/requests/BaseToken.go new file mode 100644 index 0000000..7ef1eec --- /dev/null +++ b/api/requests/BaseToken.go @@ -0,0 +1,46 @@ +package requests + +type BaseTokenRequest struct { + GetTokenPage // 获取列表-分页 + GetTokenList // 获取列表 + AddBaseToken // 新增 + PutBaseToken // 修改 +} + +// GetTokenPage 获取列表-分页 +type GetTokenPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` +} + +// GetTokenList 获取列表 +type GetTokenList struct { + TokenId string `json:"token_id" form:"token_id" label:"主键id"` // 主键id + TokenName string `json:"token_name" form:"token_name" label:"名称"` // 名称 +} + +// AddBaseToken 新增 +type AddBaseToken struct { + TokenName string `json:"token_name" form:"token_name" label:"名称" validate:"required"` // 名称 + BaseTokenItem []AddBaseTokenItem `json:"base_token_item" form:"base_token_item" label:"明细" validate:"required"` +} + +// AddBaseTokenItem 新增-明细 +type AddBaseTokenItem struct { + ItemName string `json:"item_name" form:"item_name" label:"名称" validate:"required"` + ItemImage string `json:"item_image" form:"item_image" label:"图片地址" validate:"required"` + ItemSort int `json:"item_sort" form:"item_sort" label:"排序(越大越靠前)" validate:"required"` +} + +// PutBaseToken 修改 +type PutBaseToken struct { + TokenName string `json:"token_name" form:"token_name" label:"名称" validate:"required"` // 名称 + BaseTokenItem []AddBaseTokenItem `json:"base_token_item" form:"base_token_item" label:"明细" validate:"required"` +} + +// PutBaseTokenItem 修改-明细 +type PutBaseTokenItem struct { + ItemName string `json:"item_name" form:"item_name" label:"名称" validate:"required"` + ItemImage string `json:"item_image" form:"item_image" label:"图片地址" validate:"required"` + ItemSort int `json:"item_sort" form:"item_sort" label:"排序(越大越靠前)" validate:"required"` +} diff --git a/api/requests/BaseTokenItem.go b/api/requests/BaseTokenItem.go new file mode 100644 index 0000000..ce2daef --- /dev/null +++ b/api/requests/BaseTokenItem.go @@ -0,0 +1,27 @@ +package requests + +type BaseTokenItemRequest struct { + GetBaseTokenItemPage // 获取列表-分页 + GetBaseTokenItemList // 获取列表 + AddItem // 新增 +} + +// GetBaseTokenItemPage 获取列表-分页 +type GetBaseTokenItemPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + TokenId string `json:"token_id" form:"token_id" label:"飞花令id"` +} + +// GetBaseTokenItemList 获取列表 +type GetBaseTokenItemList struct { + ItemId string `json:"item_id" form:"item_id" label:"主键id"` // 主键id + TokenId string `json:"token_id" form:"token_id" label:"飞花令id"` + ItemName string `json:"item_name" form:"item_name" label:"名称"` +} + +// AddItem 新增 +type AddItem struct { + TokenId string `json:"token_id" form:"token_id" label:"飞花令id"` + ItemName string `json:"item_name" form:"item_name" label:"名称"` +} diff --git a/api/requests/QuestionQa.go b/api/requests/QuestionQa.go index ce82f1e..facc219 100644 --- a/api/requests/QuestionQa.go +++ b/api/requests/QuestionQa.go @@ -31,17 +31,18 @@ type GetQuestionQaPageOrder struct { // AddQuestionQa 新增问答题库 type AddQuestionQa struct { - QaName string `json:"qa_name" form:"qa_name" label:"名称" validate:"required"` - QaRuleContent string `json:"qa_rule_content" form:"qa_rule_content" label:"规则解释" validate:"required"` - QaQuantity int `json:"qa_quantity" form:"qa_quantity" label:"题目数量" validate:"required,number,min=1"` - QaDisplayType int `json:"qa_display_type" form:"qa_display_type" label:"展示类型" validate:"required,oneof=1 2"` // (1:常规 2:飞花令) - QaExpireTime string `json:"qa_expire_time" form:"qa_expire_time" label:"过期时间" validate:"required"` // 注意:这里假设LocalTime转换为字符串格式处理 - QaPassword string `json:"qa_password" form:"qa_password" label:"分享密码" validate:"required"` - Image string `json:"image" form:"image" label:"背景图" validate:"required"` - Item []AddQuestionQaItem `json:"item" form:"item" label:"明细" validate:"required"` + QaName string `json:"qa_name" form:"qa_name" label:"名称" validate:"required"` + QaRuleContent string `json:"qa_rule_content" form:"qa_rule_content" label:"规则解释" validate:"required"` + QaQuantity int `json:"qa_quantity" form:"qa_quantity" label:"题目数量" validate:"required,number,min=1"` + QaDisplayType int `json:"qa_display_type" form:"qa_display_type" label:"展示类型" validate:"required,oneof=1 2"` // (1:常规 2:飞花令) + QaExpireTime string `json:"qa_expire_time" form:"qa_expire_time" label:"过期时间" validate:"required"` // 注意:这里假设LocalTime转换为字符串格式处理 + QaPassword string `json:"qa_password" form:"qa_password" label:"分享密码" validate:"required"` + Image string `json:"image" form:"image" label:"背景图" validate:"required"` + QuestionQaItem []AddQuestionQaItem `json:"question_qa_item" form:"question_qa_item" label:"题目明细" validate:"required"` + BaseTokenItem []AddQuestionQaBaseTokenItem `json:"base_token_item" form:"base_token_item" label:"飞花令明细"` // 展示类型为飞花令时存在 } -// AddQuestionQaItem 新增问答题库-明细 +// AddQuestionQaItem 新增问答题库-题目明细 type AddQuestionQaItem struct { QuestionType int `json:"question_type" form:"question_type" validate:"required,number,oneof=1 2 3 4" label:"题目类型"` // 题目类型(1:单选 2:多选 3:问答 4:判断) FirstLabelId string `json:"first_label_id" form:"first_label_id" validate:"required" label:"一级标签id"` @@ -50,17 +51,23 @@ type AddQuestionQaItem struct { Quantity int `json:"quantity" form:"quantity" validate:"required,number,min=1" label:"数量"` } +// AddQuestionQaBaseTokenItem 新增问答题库-飞花令明细 +type AddQuestionQaBaseTokenItem struct { + TokenId string `json:"token_id" form:"token_id" label:"飞花令明细id" validate:"required"` +} + // PutQuestionQa 修改问答题库 type PutQuestionQa struct { - QaName string `json:"qa_name" form:"qa_name" label:"名称" validate:"required"` - QaRuleContent string `json:"qa_rule_content" form:"qa_rule_content" label:"规则解释" validate:"required"` - QaQuantity int `json:"qa_quantity" form:"qa_quantity" label:"题目数量" validate:"required,number,min=1"` - QaDisplayType int `json:"qa_display_type" form:"qa_display_type" label:"展示类型" validate:"required,oneof=1 2"` // (1:常规 2:飞花令) - QaExpireTime string `json:"qa_expire_time" form:"qa_expire_time" label:"过期时间" validate:"required"` // 注意:这里假设LocalTime转换为字符串格式处理 - QaPassword string `json:"qa_password" form:"qa_password" label:"分享密码" validate:"required"` - Image string `json:"image" form:"image" label:"背景图" validate:"required"` - Item []AddQuestionQaItem `json:"item" form:"item" label:"明细" validate:"required"` - Action int `json:"action" form:"action" label:"动作" validate:"required,oneof=1 2"` // 1:正常修改 2:重新生成题库 + QaName string `json:"qa_name" form:"qa_name" label:"名称" validate:"required"` + QaRuleContent string `json:"qa_rule_content" form:"qa_rule_content" label:"规则解释" validate:"required"` + QaQuantity int `json:"qa_quantity" form:"qa_quantity" label:"题目数量" validate:"required,number,min=1"` + QaDisplayType int `json:"qa_display_type" form:"qa_display_type" label:"展示类型" validate:"required,oneof=1 2"` // (1:常规 2:飞花令) + QaExpireTime string `json:"qa_expire_time" form:"qa_expire_time" label:"过期时间" validate:"required"` // 注意:这里假设LocalTime转换为字符串格式处理 + QaPassword string `json:"qa_password" form:"qa_password" label:"分享密码" validate:"required"` + Image string `json:"image" form:"image" label:"背景图" validate:"required"` + QuestionQaItem []PutQuestionQaItem `json:"question_qa_item" form:"question_qa_item" label:"题目明细" validate:"required"` + Action int `json:"action" form:"action" label:"动作" validate:"required,oneof=1 2"` // 1:正常修改 2:重新生成题库 + BaseTokenItem []PutQuestionQaBaseTokenItem `json:"base_token_item" form:"base_token_item" label:"飞花令明细"` // 展示类型为飞花令时存在 } // PutQuestionQaItem 修改问答题库-明细 @@ -72,6 +79,11 @@ type PutQuestionQaItem struct { Quantity int `json:"quantity" form:"quantity" validate:"required,number,min=1" label:"数量"` } +// PutQuestionQaBaseTokenItem 修改问答题库-飞花令明细 +type PutQuestionQaBaseTokenItem struct { + TokenId string `json:"token_id" form:"token_id" label:"飞花令明细id" validate:"required"` +} + // PutQuestionQaPassword 修改问答题库密码 type PutQuestionQaPassword struct { QaPassword string `json:"qa_password" form:"qa_password" label:"分享密码" validate:"required"` diff --git a/api/router/router.go b/api/router/router.go index 4171843..33f9d53 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -77,6 +77,10 @@ func publicRouter(r *gin.Engine, api controller.Api) { migrateGroup.GET("", api.Migrate.Migrate) } + // 获取分享数据 + r.GET("/share", api.Share.GetShare) + + // 后台 adminGroup := r.Group("/admin") { // 验证码 @@ -90,13 +94,6 @@ func publicRouter(r *gin.Engine, api controller.Api) { // 修改题目 adminGroup.PUT("/question/test/:question_id", api.Question.PutQuestionTest) - - // 分享 - shareGroup := r.Group("/share") - { - // 获取分享数据 - shareGroup.GET("", api.Share.GetShare) - } } } @@ -174,17 +171,47 @@ func privateRouter(r *gin.Engine, api controller.Api) { } } - // 标签 - labelGroup := adminGroup.Group("/label") + // 基础数据 + baseGroup := adminGroup.Group("/base") { - // 获取标签列表 - labelGroup.GET("/list", api.Label.GetLabelList) + // 标签 + labelGroup := baseGroup.Group("/label") + { + // 获取标签列表 + labelGroup.GET("/list", api.Label.GetLabelList) - // 新增标签 - labelGroup.POST("", api.Label.AddLabel) + // 新增标签 + labelGroup.POST("", api.Label.AddLabel) - // 修改标签 - labelGroup.PUT("/:label_id", api.Label.PutLabel) + // 修改标签 + labelGroup.PUT("/:label_id", api.Label.PutLabel) + } + + // 飞花令 + tokenGroup := baseGroup.Group("/token") + { + // 获取列表-分页 + tokenGroup.GET("/page", api.BaseToken.GetTokenPage) + + // 获取列表 + tokenGroup.GET("/list", api.BaseToken.GetTokenList) + + // 新增 + tokenGroup.POST("", api.BaseToken.AddBaseToken) + + // 修改 + tokenGroup.PUT("/:token_id", api.BaseToken.PutBaseToken) + + // 飞花令明细 + itemGroup := tokenGroup.Group("/item") + { + // 获取列表-分页 + itemGroup.GET("/page", api.BaseTokenItem.GetBaseTokenItemPage) + + // 获取列表 + itemGroup.GET("/list", api.BaseTokenItem.GetBaseTokenItemList) + } + } } // 统计 diff --git a/api/service/AdminUser.go b/api/service/AdminUser.go index 69f68da..29234e2 100644 --- a/api/service/AdminUser.go +++ b/api/service/AdminUser.go @@ -48,6 +48,7 @@ func (r *AdminUserService) Login(req requests.Login) (res *dto.AdminUserDto, err token := &utils.Token{ UserId: strconv.FormatInt(adminUser.UserId, 10), + Client: 2, } // 生成jwt diff --git a/api/service/QuestionQa.go b/api/service/QuestionQa.go index 4e8b5f3..e8e0dac 100644 --- a/api/service/QuestionQa.go +++ b/api/service/QuestionQa.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/goccy/go-json" "knowledge/api/dao" - "knowledge/api/dto" "knowledge/api/model" "knowledge/api/requests" "knowledge/global" @@ -43,7 +42,10 @@ func (r *QuestionQaService) AddQuestionQa(req requests.AddQuestionQa) (bool, err } // 处理明细选题规则 - itemContent, _ := json.Marshal(req.Item) + questionQaItemContent, err := json.Marshal(req.QuestionQaItem) + if err != nil { + return false, errors.New("明细题目错误") + } // 开始事务 tx := global.Db.Begin() @@ -64,7 +66,7 @@ func (r *QuestionQaService) AddQuestionQa(req requests.AddQuestionQa) (bool, err QaPassword: req.QaPassword, OpenNumber: 0, Image: req.Image, - ItemContent: string(itemContent), + ItemContent: string(questionQaItemContent), } questionQaDao := dao.QuestionQaDao{} @@ -92,7 +94,7 @@ func (r *QuestionQaService) AddQuestionQa(req requests.AddQuestionQa) (bool, err // 新增问答题库题目列表 questionDao := dao.QuestionDao{} questionQaItemDao := dao.QuestionQaItemDao{} - for _, item := range req.Item { + for _, item := range req.QuestionQaItem { // 验证一级标签 firstLabelId, err := strconv.ParseInt(item.FirstLabelId, 10, 64) if err != nil { @@ -153,6 +155,7 @@ func (r *QuestionQaService) AddQuestionQa(req requests.AddQuestionQa) (bool, err return false, err } + // 新增明细题目 for _, question := range questions { questionQaItem := &model.QuestionQaItem{ QaId: questionQa.QaId, @@ -166,6 +169,38 @@ func (r *QuestionQaService) AddQuestionQa(req requests.AddQuestionQa) (bool, err } } + // 新增飞花令 + if req.QaDisplayType == 2 { + questionQaTokenDao := dao.QuestionQaTokenDao{} + baseTokenDao := dao.BaseTokenDao{} + 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 + } + + 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 + } + } + } + tx.Commit() return true, nil } @@ -181,7 +216,7 @@ func (r *QuestionQaService) PutQuestionQa(qaId int64, req requests.PutQuestionQa } if questionQa.QaStatus == 2 { - return false, errors.New("题库已失效") + return false, errors.New("题库已失效,请重新创建") } // 开始事务 @@ -242,9 +277,9 @@ func (r *QuestionQaService) PutQuestionQa(qaId int64, req requests.PutQuestionQa } // 处理明细选题规则 - itemContent, _ := json.Marshal(req.Item) - if string(itemContent) != questionQa.ItemContent { - questionQaData["item_content"] = string(itemContent) + questionQaItemContent, _ := json.Marshal(req.QuestionQaItem) + if string(questionQaItemContent) != questionQa.ItemContent { + questionQaData["item_content"] = string(questionQaItemContent) } // 题目数量 @@ -267,7 +302,7 @@ func (r *QuestionQaService) PutQuestionQa(qaId int64, req requests.PutQuestionQa return false, err } - for _, item := range req.Item { + for _, item := range req.QuestionQaItem { // 验证一级标签 firstLabelId, err := strconv.ParseInt(item.FirstLabelId, 10, 64) if err != nil { @@ -350,6 +385,47 @@ func (r *QuestionQaService) PutQuestionQa(qaId int64, req requests.PutQuestionQa } } + // 删除飞花令 + 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{} + 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 + } + + 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 + } + } + } + tx.Commit() return true, nil } @@ -480,24 +556,3 @@ func (r *QuestionQaService) PutQuestionQaRule(qaId int64, req requests.PutQuesti 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 -} diff --git a/api/service/Share.go b/api/service/Share.go deleted file mode 100644 index 4c2d730..0000000 --- a/api/service/Share.go +++ /dev/null @@ -1,106 +0,0 @@ -package service - -import ( - "errors" - "knowledge/api/dao" - "knowledge/api/dto" - "knowledge/api/requests" - "sort" - "time" -) - -type ShareService struct { -} - -func (r *ShareService) GetShare(req requests.GetShare) (g *dto.ShareDto, err error) { - questionQaDao := dao.QuestionQaDao{} - questionQaItemDao := dao.QuestionQaItemDao{} - questionDao := dao.QuestionDao{} - - // 获取题库数据 - maps := make(map[string]interface{}) - maps["qa_share_id"] = req.QaShareId - questionQa, err := questionQaDao.GetQuestionQa(maps) - if err != nil || questionQa == nil { - return nil, errors.New("题库不存在") - } - - if questionQa.QaStatus == 2 { - return nil, errors.New("题库已失效") - } - - if questionQa.QaPassword != req.QaPassword { - return nil, errors.New("密码错误") - } - - // 检测过期时间 - now := time.Now() - qaExpireTime := time.Time(questionQa.QaExpireTime) - if qaExpireTime.Before(now) { - return nil, errors.New("题库已失效") - } - - // 加载题库数据 - g = &dto.ShareDto{} - g.QuestionQa = dto.GetQuestionQaDto(questionQa) - - // 获取题库明细数据-必备选中 - maps = make(map[string]interface{}) - maps["qa_id"] = questionQa.QaId - maps["is_must_select"] = 1 - questionQaItems, err := questionQaItemDao.GetQuestionQaItemList(maps) - if err == nil && len(questionQaItems) > 0 { - shareQuestionDtos := make([]*dto.ShareQuestionDto, len(questionQaItems)) - - for i, item := range questionQaItems { - // 获取题目数据 - question, err := questionDao.GetQuestionById(item.QuestionId) - if err != nil { - return nil, errors.New("题目错误") - } - - shareQuestionDto := dto.GetShareQuestionDto(question) - - shareQuestionDto.IsMustSelect = item.IsMustSelect - - // 将转换后的结构体添加到新切片中 - shareQuestionDtos[i] = shareQuestionDto - } - - g.Question = shareQuestionDtos - } - - // 计算剩余题目数量 - 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.GetQuestionQaItemListRand(maps, 1) - if err == nil && len(questionQaItems) > 0 { - for _, item := range questionQaItems { - // 获取题目数据 - question, err := questionDao.GetQuestionById(item.QuestionId) - if err != nil { - return nil, errors.New("题目错误") - } - - shareQuestionDto := dto.GetShareQuestionDto(question) - - shareQuestionDto.IsMustSelect = item.IsMustSelect - - // 将转换后的结构体添加到新切片中 - g.Question = append(g.Question, shareQuestionDto) - } - } - } - - // 按照难度重新排序题目顺序 - sort.SliceStable(g.Question, func(i, j int) bool { - return g.Question[i].Difficulty < g.Question[j].Difficulty - }) - - return g, nil -} diff --git a/config.yaml b/config.yaml index c20c62c..e5912e1 100644 --- a/config.yaml +++ b/config.yaml @@ -27,7 +27,7 @@ redis: port: 30002 password: gdxz2022&dj. pool-size: 100 - db: 1 + db: 5 # [jwt] jwt: diff --git a/utils/jwt.go b/utils/jwt.go index 2ae4740..6efa9fb 100644 --- a/utils/jwt.go +++ b/utils/jwt.go @@ -8,6 +8,7 @@ import ( type Token struct { UserId string `json:"user_id"` // 用户id + Client int `json:"client"` // 客户端(1:前台 2:后台) jwt.RegisteredClaims // v5版本新加的方法 }