question.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package model
  2. import (
  3. "aiChat/internal/consts"
  4. "aiChat/utility"
  5. "context"
  6. "fmt"
  7. "github.com/gogf/gf/v2/frame/g"
  8. "github.com/gogf/gf/v2/util/gconv"
  9. "regexp"
  10. "strings"
  11. )
  12. var (
  13. Question = &cQuestion{}
  14. regExpSmart = regexp.MustCompile("smart_\\S+_smart")
  15. )
  16. const (
  17. Answer_UsuallyProblem = iota + 1
  18. Answer_Isbusiness
  19. Answer_ChatGPT
  20. )
  21. type cQuestion struct {
  22. }
  23. type BaseQuestion struct {
  24. Prompt string `json:"prompt"`
  25. History [][]string `json:"history"`
  26. }
  27. type QuestionReq struct {
  28. *BaseQuestion
  29. Href string `json:"href"` //咨询页面
  30. }
  31. // GetGuessQuestion 猜你想问
  32. func (q *cQuestion) GetGuessQuestion(ctx context.Context, limit int) (list []string, err error) {
  33. list = make([]string, 0, limit)
  34. res, err := g.Model("ai_question_list").Ctx(ctx).Fields("question").
  35. Where("status = 1 and question_type = ?", consts.QUESTION_TYPE_GUESS).OrderDesc("id").Limit(limit).All()
  36. if err != nil {
  37. return nil, err
  38. }
  39. for _, m := range res.List() {
  40. list = append(list, gconv.String(m["question"]))
  41. }
  42. return
  43. }
  44. // GetUsuallyProblem 获取常见问题
  45. func (q *cQuestion) GetUsuallyProblem(ctx context.Context, scenario, limit int) (list []string, err error) {
  46. list = make([]string, 0, limit)
  47. res, err := g.Model("ai_question_list").Ctx(ctx).Fields("question").
  48. Where("status = 1 and question_type = ? and source = ?", consts.QUESTION_TYPE_USUALLY, scenario).OrderDesc("id").Limit(limit).All()
  49. if err != nil {
  50. return nil, err
  51. }
  52. for _, m := range res.List() {
  53. list = append(list, gconv.String(m["question"]))
  54. }
  55. return
  56. }
  57. type BusinessRes struct {
  58. CheckMember int `json:"check_member" dc:"是否校验大会员权限"`
  59. Answer string `json:"answer" dc:"答案"`
  60. AutoUrl string `json:"auto_url" dc:"默认url"`
  61. Joggle string `json:"joggle" dc:"业务接口"`
  62. Noperm string `json:"noperm" dc:"无权限回复"`
  63. Source string `json:"source" dc:"问题所属"`
  64. ServiceId string `json:"service_id" dc:"大会员功能服务id"`
  65. }
  66. // getIsbusinessData 获取业务规则
  67. func (q *cQuestion) getIsbusinessData(ctx context.Context, code string) (bRes *BusinessRes, err error) {
  68. res, err := g.Model("ai_question").Ctx(ctx).Fields("check_member", "answer", "auto_url", "joggle", "noperm", "source", "service_id").Where("ai_code = ?", code).One()
  69. if err != nil {
  70. return nil, err
  71. }
  72. if res.IsEmpty() {
  73. return nil, fmt.Errorf("未知业务指令")
  74. }
  75. bRes = &BusinessRes{}
  76. if err = res.Struct(bRes); err != nil {
  77. return nil, err
  78. }
  79. return bRes, nil
  80. }
  81. // DetailQuestion 问题处理
  82. func (q *cQuestion) DetailQuestion(ctx context.Context, qRes *QuestionReq) (reply string, from int, err error) {
  83. cRes, err := ChatGpt.Do(ctx, qRes)
  84. if err != nil {
  85. return "", 0, err
  86. }
  87. // 校验是否有业务逻辑
  88. matchArr := regExpSmart.FindStringSubmatch(cRes.Response)
  89. if len(matchArr) == 0 {
  90. return cRes.Response, Answer_ChatGPT, nil
  91. }
  92. // 查询业务逻辑
  93. var bRes = &BusinessRes{}
  94. bRes, err = q.getIsbusinessData(ctx, matchArr[0])
  95. // 权限校验
  96. jSession := SessionCtx.Get(ctx).JSession
  97. powerPass := func() bool {
  98. power := utility.Middleground.PowerCheckCenter.Check(g.Config().MustGet(ctx, "chat.appId").String(), jSession.UserId, jSession.NewUid, jSession.AccountId, jSession.EntId, jSession.PositionType, jSession.PositionId)
  99. // 大会员权益校验
  100. if bRes.CheckMember == 1 && power.Member.Status <= 0 {
  101. return false
  102. }
  103. // 大会员权益ServiceId校验
  104. if bRes.ServiceId != "" {
  105. for _, v := range strings.Split(bRes.ServiceId, ",") {
  106. var ok bool = false
  107. for _, vv := range power.Member.MemberPowerList {
  108. if gconv.Int64(v) == vv {
  109. ok = true
  110. break
  111. }
  112. }
  113. if !ok {
  114. return false
  115. }
  116. }
  117. }
  118. return true
  119. }()
  120. if !powerPass {
  121. return bRes.Noperm, Answer_Isbusiness, nil
  122. }
  123. _, infoId := GetScenarioAndInfoId(qRes.Href)
  124. if bRes.Source == scenarioName[DetailPage] && infoId == "" {
  125. return bRes.AutoUrl, Answer_Isbusiness, nil
  126. }
  127. businessRes, err := utility.DoBusiness(ctx, bRes.Joggle, &utility.RpcParams{
  128. UserId: jSession.UserId,
  129. Answer: bRes.Answer,
  130. BiddingId: infoId,
  131. IsEnt: false,
  132. BaseUserId: jSession.NewUid,
  133. })
  134. if err != nil {
  135. return "", Answer_Isbusiness, nil
  136. }
  137. if businessRes.ErrMsg != "" {
  138. return "", Answer_Isbusiness, fmt.Errorf(businessRes.ErrMsg)
  139. }
  140. return businessRes.ReplyMsg, Answer_Isbusiness, nil
  141. }