feat kafka 改版 2

This commit is contained in:
2026-01-30 11:02:53 +08:00
parent defe0b8fff
commit 39fa373c01
22 changed files with 1297 additions and 236 deletions

View File

@@ -5,16 +5,13 @@ import (
"encoding/json"
"errors"
"fmt"
"git.hlsq.asia/mmorpg/service-common/db/kafka"
"git.hlsq.asia/mmorpg/service-common/db/redis"
"git.hlsq.asia/mmorpg/service-common/log"
"git.hlsq.asia/mmorpg/service-common/net/http/http_resp"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
"git.hlsq.asia/mmorpg/service-common/utils"
"git.hlsq.asia/mmorpg/service-qgdzs/internal/ai"
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/model"
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/repository"
"git.hlsq.asia/mmorpg/service-qgdzs/internal/timer"
"gorm.io/gorm"
"time"
)
@@ -30,7 +27,7 @@ var prompt = []string{`
"question": "题目文本", // 简洁30字以内
"options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"], // 提供4个选项A/B/C/D其中仅1个正确
"answer": "C", // 答案
"explanation": "解析文本", // 200字以内尽量幽默有趣
"explanation": "解析文本", // 200字以内尽量幽默有趣,不要在文本中说正确和错误,因为不知道用户选的哪个
"category": "分类", // 尽量从上述分类中选择,你也可以增加,但是命名风格要类似
"difficulty": 100, // 难度分 0 - 100
}]
@@ -57,16 +54,20 @@ type Question struct {
}
func (s *Server) GenerateQuestion(ctx context.Context, req *grpc_pb.GenerateQuestionReq) (*grpc_pb.GenerateQuestionResp, error) {
categoryDao := repository.NewCategoryDao(ctx, redis.GetCacheClient())
categoryDao := repository.NewCategoryDao(ctx, s.query, redis.GetCacheClient())
category, err := categoryDao.FindAll()
if err != nil {
return nil, utils.ErrorsWrap(err)
}
categoryName := make([]string, 0)
for _, c := range category {
categoryName = append(categoryName, c.Category)
}
question := make([]*Question, 0)
err = ai.NewAIClient(false, "", 0.9).
RequestAI(
[]string{
fmt.Sprintf(prompt[0], time.Now().Format("2006-01-02 15:04:05"), category),
fmt.Sprintf(prompt[0], time.Now().Format("2006-01-02 15:04:05"), categoryName),
fmt.Sprintf(prompt[1], req.Num),
fmt.Sprintf(prompt[2], req.Num),
fmt.Sprintf(prompt[3], req.Num),
@@ -89,7 +90,7 @@ func (s *Server) GenerateQuestion(ctx context.Context, req *grpc_pb.GenerateQues
return nil, utils.ErrorsWrap(err)
}
questionDao := repository.NewQuestionDao(ctx, redis.GetCacheClient())
questionDao := repository.NewQuestionDao(ctx, s.query, redis.GetCacheClient())
for _, q := range question {
marshal, _ := json.Marshal(q.Options)
categorySn, err := categoryDao.FindSnByName(q.Category)
@@ -121,116 +122,3 @@ func (s *Server) GenerateQuestion(ctx context.Context, req *grpc_pb.GenerateQues
}
return nil, nil
}
// GetQuestion 获取题目
func (s *Server) GetQuestion(ctx context.Context, req *grpc_pb.GetQuestionReq) (*grpc_pb.GetQuestionResp, error) {
question, err := repository.NewQuestionDao(ctx).FindByRandom(req.CategorySn)
if err != nil {
return nil, utils.ErrorsWrap(err)
}
options := make([]string, 0)
if err = json.Unmarshal([]byte(question.Options), &options); err != nil {
return nil, utils.ErrorsWrapF(err, "data: %v", question.Options)
}
category, _ := repository.NewCategoryDao(ctx).FindNameBySn(question.CategorySn)
return &grpc_pb.GetQuestionResp{
Sn: question.Sn,
Question: question.Question,
Options: options,
Category: category,
Difficulty: question.Difficulty,
}, nil
}
// GetQuestionInfo 获取具体的题目
func (s *Server) GetQuestionInfo(ctx context.Context, req *grpc_pb.GetQuestionInfoReq) (*grpc_pb.GetQuestionInfoResp, error) {
question, err := repository.NewQuestionDao(ctx).FindBySn(req.QuestionSn)
if err != nil {
return nil, utils.ErrorsWrap(err)
}
options := make([]string, 0)
if err = json.Unmarshal([]byte(question.Options), &options); err != nil {
return nil, utils.ErrorsWrapF(err, "data: %v", question.Options)
}
category, _ := repository.NewCategoryDao(ctx).FindNameBySn(question.CategorySn)
return &grpc_pb.GetQuestionInfoResp{
Question: question.Question,
Options: options,
Category: category,
Difficulty: question.Difficulty,
Explanation: question.Explanation,
}, nil
}
// AnswerQuestion 回答题目
func (s *Server) AnswerQuestion(ctx context.Context, req *grpc_pb.AnswerQuestionReq) (*grpc_pb.AnswerQuestionResp, error) {
question, err := repository.NewQuestionDao(ctx).FindBySn(req.Sn)
if err != nil {
return nil, utils.ErrorsWrap(err)
}
options := make([]string, 0)
if err = json.Unmarshal([]byte(question.Options), &options); err != nil {
return nil, utils.ErrorsWrapF(err, "data: %v", question.Options)
}
// 保存答题记录
if utils.ShouldBindUsn(ctx, &req.USN) {
data := &timer.TopicQuestionAnswer{
MessageSn: utils.SnowflakeInstance().Generate().String(),
USN: req.USN,
QuestionSn: question.Sn,
QuestionAnswer: question.Answer,
Answer: req.Answer,
}
marshal, _ := json.Marshal(data)
kafka.NewProducer().Produce(ctx, "qgdzs.question.answer", string(marshal))
}
return &grpc_pb.AnswerQuestionResp{
Answer: question.Answer,
Explanation: question.Explanation,
}, nil
}
// GetAllCategory 获取所有类目
func (s *Server) GetAllCategory(ctx context.Context, req *grpc_pb.GetAllCategoryReq) (*grpc_pb.GetAllCategoryResp, error) {
categoryList, err := repository.NewCategoryDao(ctx).FindAll()
if err != nil {
return nil, utils.ErrorsWrap(err)
}
categories := make([]*grpc_pb.GetAllCategoryItem, 0)
for _, category := range categoryList {
categories = append(categories, &grpc_pb.GetAllCategoryItem{
Sn: category.Sn,
Category: category.Category,
})
}
return &grpc_pb.GetAllCategoryResp{
Categories: categories,
}, nil
}
// GetRecord 获取答题记录
func (s *Server) GetRecord(ctx context.Context, req *grpc_pb.GetRecordReq) (*grpc_pb.GetRecordResp, error) {
if !utils.ShouldBindUsn(ctx, &req.USN) {
return nil, http_resp.ParamError
}
records, count, err := repository.NewRecordDao(ctx).FindByUSN(req.USN, int(req.Page), int(req.PageSize))
if err != nil {
return nil, utils.ErrorsWrap(err)
}
resp := make([]*grpc_pb.GetRecordItem, 0)
for _, record := range records {
resp = append(resp, &grpc_pb.GetRecordItem{
QuestionSn: record.QuestionSn,
Question: record.Question,
Difficulty: record.Difficulty,
Category: record.Category,
QuestionAnswer: record.QuestionAnswer,
Answer: record.Answer,
CreateTime: record.CreatedAt.Unix(),
})
}
return &grpc_pb.GetRecordResp{
Count: int32(count),
Records: resp,
}, nil
}