feCalendar_ai.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package services
  2. import (
  3. "errors"
  4. "eta/eta_api/models"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/models/fe_calendar"
  7. "eta/eta_api/models/system"
  8. "eta/eta_api/services/data"
  9. "eta/eta_api/utils"
  10. "eta/eta_api/utils/llm"
  11. "eta/eta_api/utils/llm/eta_llm"
  12. "fmt"
  13. "net/http"
  14. "strings"
  15. "time"
  16. )
  17. func GetFeCalendarAiArticle(req *fe_calendar.FeCalendarAiArticleGenerateReq, matterDateTime time.Time, edbInfo *data_manage.EdbInfo, sysUser *system.Admin) (ret *fe_calendar.FeCalendarAiArticleGenerateResp, err error) {
  18. defer func() {
  19. if err != nil {
  20. utils.FileLog.Error(fmt.Sprintf("获取AI文章失败: %s", err.Error()))
  21. }
  22. }()
  23. var endDate string
  24. if edbInfo.EndDate <= req.MatterDate {
  25. endDate = edbInfo.EndDate
  26. }else{
  27. month := matterDateTime.Month()
  28. year := matterDateTime.Year()
  29. endDate = time.Date(year, month+1, 1, 0, 0, 0, 0, matterDateTime.Location()).AddDate(0, 0, -1).Format(utils.FormatDate)
  30. }
  31. classifyList, err, errMsg := data.GetFullClassifyByClassifyId(edbInfo.ClassifyId)
  32. if err != nil {
  33. err = errors.New(errMsg)
  34. return
  35. }
  36. classifyName := ""
  37. for _, v := range classifyList {
  38. classifyName += v.ClassifyName + "/"
  39. }
  40. edbData := make([]*data_manage.EdbDataList, 0)
  41. switch edbInfo.EdbInfoType {
  42. case 0: //普通源指标
  43. //dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfoId, startDateReal, endDate)
  44. // 获取指标数据
  45. edbData, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, "", endDate)
  46. if err != nil {
  47. err = errors.New("获取指标数据失败, Err: " + err.Error())
  48. return
  49. }
  50. case 1: //预测指标
  51. edbData, _, _, err, _ = data.GetPredictDataListByPredictEdbInfo(edbInfo, "", endDate, true)
  52. if err != nil {
  53. err = errors.New("获取预测指标数据失败, Err: " + err.Error())
  54. return
  55. }
  56. }
  57. if len(edbData) == 0 {
  58. err = errors.New("指标数据为空")
  59. return
  60. }
  61. dataStr := "日期 值\n"
  62. for _, v := range edbData {
  63. dataStr += fmt.Sprintf("%s %f.8\n", v.DataTime, v.Value)
  64. }
  65. endDate = edbData[len(edbData) - 1].DataTime
  66. // 获取提示词内容
  67. promote := models.BusinessConfMap[models.BusinessConfFeCalendarAiArticlePromote]
  68. // 调用大模型的接口
  69. edbName := edbInfo.EdbName
  70. frequency := edbInfo.Frequency
  71. startDate := edbInfo.StartDate
  72. sourceName := edbInfo.SourceName
  73. llmService, _ := llm.GetInstance(llm.ETA_LLM_CLIENT)
  74. promote = fmt.Sprintf(promote, edbName, frequency, startDate, endDate, sourceName, dataStr, classifyName)
  75. resp, err := llmService.CompletionChat(promote, nil)
  76. if err != nil {
  77. err = errors.New("获取AI文章失败, Err: " + err.Error())
  78. return
  79. }
  80. defer func() {
  81. if resp != nil && resp.Body != nil && err == nil {
  82. _ = resp.Body.Close()
  83. }
  84. }()
  85. if resp == nil {
  86. err = errors.New("知识库问答失败: 无应答")
  87. return
  88. }
  89. if err != nil {
  90. err = errors.New(fmt.Sprintf("知识库问答失败: httpCode:%d,错误信息:%s", resp.StatusCode, http.StatusText(resp.StatusCode)))
  91. return
  92. }
  93. if resp.StatusCode != http.StatusOK {
  94. utils.FileLog.Error(fmt.Sprintf("知识库问答失败: httpCode:%d,错误信息:%s", resp.StatusCode, http.StatusText(resp.StatusCode)))
  95. err = errors.New(fmt.Sprintf("知识库问答失败: httpCode:%d,错误信息:%s", resp.StatusCode, http.StatusText(resp.StatusCode)))
  96. return
  97. }
  98. text := ""
  99. // 解析流式响应
  100. contentChan, errChan, closeChan, _ := eta_llm.ParseStreamResponse(resp)
  101. for {
  102. select {
  103. case content, ok := <-contentChan:
  104. if !ok {
  105. err = errors.New("未知的内容错误异常")
  106. // 标记llm提问状态:未提问
  107. return nil, err
  108. }
  109. text += content
  110. case chanErr, ok := <-errChan:
  111. if !ok {
  112. err = errors.New("未知的错误异常")
  113. } else if chanErr != nil {
  114. err = errors.New(chanErr.Error())
  115. }
  116. // 标记llm提问状态:未提问
  117. return nil, err
  118. case <-closeChan:
  119. goto LOOP_END
  120. }
  121. }
  122. LOOP_END:
  123. // 过滤掉<think>块内容
  124. if thinkStart := strings.Index(text, "<think>"); thinkStart != -1 {
  125. if thinkEnd := strings.Index(text, "</think>"); thinkEnd != -1 {
  126. // 提取<think>之前和</think>之后的内容
  127. text = text[:thinkStart] + text[thinkEnd+len("</think>"):]
  128. }
  129. }
  130. // 去除可能存在的多余空行
  131. text = strings.TrimSpace(text)
  132. // 获取品种信息
  133. // permissionItem, err := models.GetChartPermissionById(req.ChartPermissionId)
  134. // if err != nil {
  135. // err = errors.New("获取品种信息失败, Err: " + err.Error())
  136. // return
  137. // }
  138. // article := new(fe_calendar.FeCalendarAiArticle)
  139. // article.Title = edbInfo.EdbName
  140. // article.Content = text
  141. // article.Prompt = promote
  142. // article.ChartPermissionId = req.ChartPermissionId
  143. // article.ChartPermissionName = permissionItem.PermissionName
  144. // article.EdbCode = edbInfo.EdbCode
  145. // article.EdbInfoId = edbInfo.EdbInfoId
  146. // article.MatterDate = req.MatterDate
  147. // article.MatterMonth = req.MatterDate
  148. // article.SysUserId = sysUser.AdminId
  149. // article.SysUserName = sysUser.RealName
  150. // // 设置月份
  151. // article.MatterMonth = matterDateTime.Format("2006-01")
  152. // err = article.Create()
  153. // if err != nil {
  154. // err = errors.New("保存AI文章失败, Err: " + err.Error())
  155. // return
  156. // }
  157. ret = &fe_calendar.FeCalendarAiArticleGenerateResp{
  158. Content: text,
  159. ModifyTime: time.Now().Format(utils.FormatDateTime),
  160. }
  161. return ret, nil
  162. }