ai_file.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. package ai
  2. import (
  3. "encoding/json"
  4. "eta/eta_api/controllers"
  5. "eta/eta_api/models"
  6. "eta/eta_api/models/aimod"
  7. "eta/eta_api/services"
  8. "eta/eta_api/services/aiser"
  9. "eta/eta_api/utils"
  10. "fmt"
  11. "os"
  12. "path"
  13. "strconv"
  14. "time"
  15. )
  16. type AiFileController struct {
  17. controllers.BaseAuthController
  18. }
  19. // @Title 文件上传
  20. // @Description 文件上传接口
  21. // @Param file query file true "文件"
  22. // @Success 200 {object} models.ResourceResp
  23. // @router /file/upload [post]
  24. func (this *AiFileController) FileUpload() {
  25. br := new(models.BaseResponse).Init()
  26. defer func() {
  27. this.Data["json"] = br
  28. this.ServeJSON()
  29. }()
  30. f, h, err := this.GetFile("file")
  31. if err != nil {
  32. br.Msg = "获取资源信息失败"
  33. br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
  34. return
  35. }
  36. uploadFileName := h.Filename //上传的文件名
  37. ext := path.Ext(h.Filename)
  38. dateDir := time.Now().Format("20060102")
  39. uploadDir := utils.STATIC_DIR + "ai/" + dateDir
  40. err = os.MkdirAll(uploadDir, utils.DIR_MOD)
  41. if err != nil {
  42. br.Msg = "存储目录创建失败"
  43. br.ErrMsg = "存储目录创建失败,Err:" + err.Error()
  44. return
  45. }
  46. randStr := utils.GetRandStringNoSpecialChar(28)
  47. fileName := randStr + ext
  48. fpath := uploadDir + "/" + fileName
  49. defer f.Close() //关闭上传文件
  50. err = this.SaveToFile("file", fpath)
  51. if err != nil {
  52. br.Msg = "文件上传失败"
  53. br.ErrMsg = "文件上传失败,Err:" + err.Error()
  54. return
  55. }
  56. resourceUrl := ``
  57. ossClient := services.NewOssClient()
  58. if ossClient == nil {
  59. br.Msg = "上传失败"
  60. br.ErrMsg = "初始化OSS服务失败"
  61. return
  62. }
  63. resourceUrl, err = ossClient.UploadFile(fileName, fpath, "")
  64. if err != nil {
  65. br.Msg = "文件上传失败"
  66. br.ErrMsg = "文件上传失败,Err:" + err.Error()
  67. return
  68. }
  69. defer func() {
  70. os.Remove(fpath)
  71. }()
  72. item := new(models.Resource)
  73. item.ResourceUrl = resourceUrl
  74. item.ResourceType = 1
  75. item.CreateTime = time.Now()
  76. newId, err := models.AddResource(item)
  77. if err != nil {
  78. br.Msg = "资源上传失败"
  79. br.ErrMsg = "资源上传失败,Err:" + err.Error()
  80. return
  81. }
  82. //调用AI接口,上传文件
  83. resp := models.ResourceResp{
  84. Id: newId,
  85. ResourceUrl: resourceUrl,
  86. ResourceName: uploadFileName,
  87. }
  88. uploadResult, err := aiser.OpenAiFileUpload(resourceUrl, uploadFileName)
  89. if err != nil {
  90. br.Msg = "文件上传失败"
  91. br.ErrMsg = "文件上传失败,Err:" + err.Error()
  92. return
  93. }
  94. if uploadResult != nil {
  95. uploadObj := new(aimod.FileUploadRecord)
  96. uploadObj.AdminId = this.SysUser.AdminId
  97. uploadObj.FileUrl = resourceUrl
  98. uploadObj.FileName = uploadFileName
  99. uploadObj.OpenaiFileId = uploadResult.Data.ID
  100. uploadObj.OpenaiFileName = uploadResult.Data.FileName
  101. uploadObj.OpenaiObject = uploadResult.Data.Object
  102. uploadObj.OpenaiStatus = uploadResult.Data.Status
  103. uploadObj.OpenaiPurpose = uploadResult.Data.Purpose
  104. uploadObj.OpenaiStatusDetails = uploadResult.Data.StatusDetails
  105. uploadObj.OpenaiCreatedAt = uploadResult.Data.CreatedAt
  106. uploadObj.CreateTime = time.Now()
  107. uploadObj.ModifyTime = time.Now()
  108. _, err = uploadObj.AddFileUploadRecord()
  109. if err != nil {
  110. br.Msg = "上传失败"
  111. br.ErrMsg = "上传失败,Err:" + err.Error()
  112. return
  113. }
  114. resp.OpenaiFileId = uploadObj.OpenaiFileId
  115. }
  116. br.Msg = "上传成功"
  117. br.Ret = 200
  118. br.Success = true
  119. br.Data = resp
  120. return
  121. }
  122. // @Title 文件检索
  123. // @Description 文件检索接口
  124. // @Param request body aimod.FileRetrieveReq true "type json string"
  125. // @Success 200 {object} models.ResourceResp
  126. // @router /file/retrieve [post]
  127. func (this *AiFileController) FileRetrieve() {
  128. br := new(models.BaseResponse).Init()
  129. defer func() {
  130. this.Data["json"] = br
  131. this.ServeJSON()
  132. }()
  133. var req aimod.FileRetrieveReq
  134. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  135. if err != nil {
  136. br.Msg = "参数解析异常!"
  137. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  138. return
  139. }
  140. if req.Ask == "" {
  141. br.Msg = "请输入提问内容!"
  142. br.ErrMsg = "请输入提问内容"
  143. return
  144. }
  145. if utils.Re == nil {
  146. key := "CACHE_CHAT_" + strconv.Itoa(this.SysUser.AdminId)
  147. cacheVal, err := utils.Rc.RedisInt(key)
  148. fmt.Println("RedisString:", cacheVal, "err:", err)
  149. if err != nil && err.Error() != "redigo: nil returned" {
  150. br.Msg = "获取数据失败!"
  151. br.ErrMsg = "获取数据失败,Err:" + err.Error()
  152. return
  153. }
  154. putVal := 0
  155. if cacheVal <= 0 {
  156. putVal = utils.AiChatLimit
  157. } else {
  158. putVal = cacheVal - 1
  159. }
  160. if putVal <= 0 {
  161. br.Msg = "您今日" + strconv.Itoa(utils.AiChatLimit) + "次问答已达上限,请明天再来!"
  162. br.ErrMsg = "您今日" + strconv.Itoa(utils.AiChatLimit) + "次问答已达上限,请明天再来!"
  163. return
  164. }
  165. lastSecond := utils.GetTodayLastSecond()
  166. utils.Rc.Put(key, putVal, lastSecond)
  167. }
  168. //根据提问,获取信息
  169. askUuid := utils.MD5(req.Ask)
  170. chatMode, err := aimod.GetAiChatByAsk(askUuid)
  171. if err != nil && err.Error() != utils.ErrNoRow() {
  172. br.Msg = "获取数据失败!"
  173. br.ErrMsg = "获取数据失败,GetAiChatByAsk,Err:" + err.Error()
  174. return
  175. }
  176. var assistantId, threadId string
  177. if req.AiChatTopicId > 0 {
  178. aiChatTopicObj := new(aimod.AiChatTopic)
  179. aiChatTopicObj.AiChatTopicId = req.AiChatTopicId
  180. topic, err := aiChatTopicObj.GetAiChatTopicById()
  181. if err != nil {
  182. if err.Error() == utils.ErrNoRow() {
  183. br.Msg = "获取数据失败!"
  184. br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
  185. return
  186. }
  187. br.Msg = "获取数据失败!"
  188. br.ErrMsg = "获取数据失败,GetAiChatTopicById,Err:" + err.Error()
  189. return
  190. }
  191. assistantId = topic.AssistantId
  192. threadId = topic.ThreadId
  193. }
  194. resp := new(aimod.ChatResp)
  195. var answer string
  196. if chatMode != nil && chatMode.Answer != "" {
  197. answer = chatMode.Answer
  198. } else {
  199. //获取主题下的所有信息
  200. //AiChatTopicId
  201. historyList, err := aimod.GetAiChatList(req.AiChatTopicId)
  202. if err != nil && err.Error() != utils.ErrNoRow() {
  203. br.Msg = "获取主题历史数据失败!"
  204. br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error()
  205. return
  206. }
  207. frList := make([]aimod.HistoryChat, 0)
  208. frItem := new(aimod.HistoryChat)
  209. frItem.Ask = req.Ask
  210. frItem.Answer = ""
  211. frList = append(frList, *frItem)
  212. for _, v := range historyList {
  213. historyFr := new(aimod.HistoryChat)
  214. historyFr.Ask = v.Ask
  215. historyFr.Answer = v.Answer
  216. frList = append(frList, *historyFr)
  217. if v.OpenaiFileId != "" {
  218. req.OpenaiFileId = append(req.OpenaiFileId, v.OpenaiFileId)
  219. }
  220. }
  221. //var assistantId,threadId string
  222. fileRetrieveResp, err := aiser.FileRetrieve(assistantId, threadId, frList, req.OpenaiFileId)
  223. if err != nil {
  224. br.Msg = "获取数据失败!"
  225. br.ErrMsg = "获取数据失败,FileRetrieve,Err:" + err.Error()
  226. return
  227. }
  228. assistantId = fileRetrieveResp.Data.AssistantId
  229. threadId = fileRetrieveResp.Data.ThreadId
  230. answer = fileRetrieveResp.Data.Answer
  231. }
  232. resp.Ask = req.Ask
  233. resp.Answer = answer
  234. if req.AiChatTopicId <= 0 { //新增
  235. topic := new(aimod.AiChatTopic)
  236. topic.TopicName = req.Ask
  237. topic.SysUserId = this.SysUser.AdminId
  238. topic.SysUserRealName = this.SysUser.RealName
  239. topic.CreateTime = time.Now()
  240. topic.ModifyTime = time.Now()
  241. topic.AssistantId = assistantId
  242. topic.ThreadId = threadId
  243. topicId, err := aimod.AddAiChatTopic(topic)
  244. if err != nil {
  245. br.Msg = "获取数据失败!"
  246. br.ErrMsg = "生成话题失败,Err:" + err.Error()
  247. return
  248. }
  249. resp.AiChatTopicId = int(topicId)
  250. chatItem := new(aimod.AiChat)
  251. chatItem.AiChatTopicId = resp.AiChatTopicId
  252. chatItem.Ask = req.Ask
  253. chatItem.AskUuid = utils.MD5(req.Ask)
  254. chatItem.Answer = answer
  255. chatItem.Model = "gpt-4-1106-preview"
  256. chatItem.SysUserId = this.SysUser.AdminId
  257. chatItem.SysUserRealName = this.SysUser.RealName
  258. chatItem.CreateTime = time.Now()
  259. chatItem.ModifyTime = time.Now()
  260. _, err = aimod.AddAiChat(chatItem)
  261. if err != nil {
  262. br.Msg = "获取数据失败!"
  263. br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
  264. return
  265. }
  266. } else {
  267. resp.AiChatTopicId = req.AiChatTopicId
  268. chatItem := new(aimod.AiChat)
  269. chatItem.AiChatTopicId = resp.AiChatTopicId
  270. chatItem.Ask = req.Ask
  271. chatItem.AskUuid = utils.MD5(req.Ask)
  272. chatItem.Answer = answer
  273. chatItem.Model = "gpt-4-1106-preview"
  274. chatItem.SysUserId = this.SysUser.AdminId
  275. chatItem.SysUserRealName = this.SysUser.RealName
  276. chatItem.CreateTime = time.Now()
  277. chatItem.ModifyTime = time.Now()
  278. _, err = aimod.AddAiChat(chatItem)
  279. if err != nil {
  280. br.Msg = "获取数据失败!"
  281. br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
  282. return
  283. }
  284. }
  285. br.Ret = 200
  286. br.Success = true
  287. br.Msg = "获取成功"
  288. br.Data = resp
  289. return
  290. }