package ai import ( "encoding/json" "eta/eta_api/controllers" "eta/eta_api/models" "eta/eta_api/models/aimod" "eta/eta_api/services" "eta/eta_api/services/aiser" "eta/eta_api/utils" "fmt" "os" "path" "strconv" "strings" "time" ) type AiFileController struct { controllers.BaseAuthController } // @Title 文件上传 // @Description 文件上传接口 // @Param File query file true "文件" // @Param AiChatTopicId query int true "主题id" // @Success 200 {object} models.ResourceResp // @router /file/upload [post] func (this *AiFileController) FileUpload() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() f, h, err := this.GetFile("File") if err != nil { br.Msg = "获取资源信息失败" br.ErrMsg = "获取资源信息失败,Err:" + err.Error() return } model := this.GetString("Model") aiChatTopicId, _ := this.GetInt("AiChatTopicId") uploadFileName := h.Filename //上传的文件名 ext := path.Ext(h.Filename) dateDir := time.Now().Format("20060102") uploadDir := utils.STATIC_DIR + "ai/" + dateDir err = os.MkdirAll(uploadDir, utils.DIR_MOD) if err != nil { br.Msg = "存储目录创建失败" br.ErrMsg = "存储目录创建失败,Err:" + err.Error() return } randStr := utils.GetRandStringNoSpecialChar(28) fileName := randStr + ext fpath := uploadDir + "/" + fileName defer f.Close() //关闭上传文件 err = this.SaveToFile("File", fpath) if err != nil { br.Msg = "文件上传失败" br.ErrMsg = "文件上传失败,Err:" + err.Error() return } resourceUrl := `` ossClient := services.NewOssClient() if ossClient == nil { br.Msg = "上传失败" br.ErrMsg = "初始化OSS服务失败" return } resourceUrl, err = ossClient.UploadFile(fileName, fpath, "") if err != nil { br.Msg = "文件上传失败" br.ErrMsg = "文件上传失败,Err:" + err.Error() return } defer func() { os.Remove(fpath) }() item := new(models.Resource) item.ResourceUrl = resourceUrl item.ResourceType = 1 item.CreateTime = time.Now() newId, err := models.AddResource(item) if err != nil { br.Msg = "资源上传失败" br.ErrMsg = "资源上传失败,Err:" + err.Error() return } //调用AI接口,上传文件 resp := models.ResourceResp{ Id: newId, ResourceUrl: resourceUrl, ResourceName: uploadFileName, } uploadResult, err := aiser.OpenAiFileUpload(resourceUrl, uploadFileName, model) if err != nil { br.Msg = "文件上传失败" br.ErrMsg = "文件上传失败,Err:" + err.Error() return } var assistantId, threadId string if aiChatTopicId > 0 { aiChatTopicObj := new(aimod.AiChatTopic) aiChatTopicObj.AiChatTopicId = aiChatTopicId topic, err := aiChatTopicObj.GetAiChatTopicById() if err != nil { if err.Error() == utils.ErrNoRow() { br.Msg = "获取数据失败!" br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error() return } br.Msg = "获取数据失败!" br.ErrMsg = "获取数据失败,GetAiChatTopicById,Err:" + err.Error() return } assistantId = topic.AssistantId threadId = topic.ThreadId } if aiChatTopicId <= 0 { //新增 topic := new(aimod.AiChatTopic) var filenameWithSuffix string filenameWithSuffix = path.Base(uploadFileName) var fileSuffix string fileSuffix = path.Ext(filenameWithSuffix) var filenameOnly string filenameOnly = strings.TrimSuffix(filenameWithSuffix, fileSuffix) topic.TopicName = filenameOnly topic.SysUserId = this.SysUser.AdminId topic.SysUserRealName = this.SysUser.RealName topic.CreateTime = time.Now() topic.ModifyTime = time.Now() topic.AssistantId = assistantId topic.ThreadId = threadId topicId, err := aimod.AddAiChatTopic(topic) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "生成话题失败,Err:" + err.Error() return } aiChatTopicId = int(topicId) chatItem := new(aimod.AiChat) chatItem.AiChatTopicId = aiChatTopicId chatItem.Ask = uploadFileName chatItem.AskUuid = utils.MD5(uploadFileName) chatItem.Model = EnabledModelsForMap[model] chatItem.SysUserId = this.SysUser.AdminId chatItem.SysUserRealName = this.SysUser.RealName if uploadResult != nil && uploadResult.Data != nil { chatItem.OpenaiFileId = uploadResult.Data.ID chatItem.OpenaiFileName = uploadFileName } chatItem.OpenaiFilePath = resourceUrl chatItem.CreateTime = time.Now() chatItem.ModifyTime = time.Now() _, err = aimod.AddAiChat(chatItem) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "生成话题记录失败,Err:" + err.Error() return } } else { chatItem := new(aimod.AiChat) chatItem.AiChatTopicId = aiChatTopicId chatItem.Ask = uploadFileName chatItem.AskUuid = utils.MD5(fileName) chatItem.Model = EnabledModelsForMap[model] chatItem.SysUserId = this.SysUser.AdminId chatItem.SysUserRealName = this.SysUser.RealName if uploadResult != nil && uploadResult.Data != nil { chatItem.OpenaiFileId = uploadResult.Data.ID chatItem.OpenaiFileName = uploadFileName } chatItem.OpenaiFilePath = resourceUrl chatItem.CreateTime = time.Now() chatItem.ModifyTime = time.Now() _, err = aimod.AddAiChat(chatItem) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "生成话题记录失败,Err:" + err.Error() return } } if uploadResult != nil && uploadResult.Data != nil && uploadResult.Data.ID != "" { uploadObj := new(aimod.FileUploadRecord) uploadObj.AdminId = this.SysUser.AdminId uploadObj.FileUrl = resourceUrl uploadObj.FileName = uploadFileName uploadObj.OpenaiFileId = uploadResult.Data.ID uploadObj.OpenaiFileName = uploadResult.Data.FileName uploadObj.OpenaiObject = uploadResult.Data.Object uploadObj.OpenaiStatus = uploadResult.Data.Status uploadObj.OpenaiPurpose = uploadResult.Data.Purpose uploadObj.OpenaiStatusDetails = uploadResult.Data.StatusDetails uploadObj.OpenaiCreatedAt = uploadResult.Data.CreatedAt uploadObj.CreateTime = time.Now() uploadObj.ModifyTime = time.Now() _, err = uploadObj.AddFileUploadRecord() if err != nil { br.Msg = "上传失败" br.ErrMsg = "上传失败,Err:" + err.Error() return } resp.OpenaiFileId = uploadObj.OpenaiFileId } resp.AiChatTopicId = aiChatTopicId br.Msg = "上传成功" br.Ret = 200 br.Success = true br.Data = resp return } // @Title 文件检索 // @Description 文件检索接口 // @Param request body aimod.FileRetrieveReq true "type json string" // @Success 200 {object} models.ResourceResp // @router /file/retrieve [post] func (this *AiFileController) FileRetrieve() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() var req aimod.FileRetrieveReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.Ask == "" { br.Msg = "请输入提问内容!" br.ErrMsg = "请输入提问内容" return } if utils.Re == nil { key := "CACHE_CHAT_" + strconv.Itoa(this.SysUser.AdminId) cacheVal, err := utils.Rc.RedisInt(key) fmt.Println("RedisString:", cacheVal, "err:", err) if err != nil && (err.Error() != "redigo: nil returned" && err.Error() != "redis: nil") { br.Msg = "获取数据失败!" br.ErrMsg = "获取数据失败,Err:" + err.Error() return } putVal := 0 if cacheVal <= 0 { putVal = utils.AiChatLimit } else { putVal = cacheVal - 1 } if putVal <= 0 { br.Msg = "您今日" + strconv.Itoa(utils.AiChatLimit) + "次问答已达上限,请明天再来!" br.ErrMsg = "您今日" + strconv.Itoa(utils.AiChatLimit) + "次问答已达上限,请明天再来!" return } lastSecond := utils.GetTodayLastSecond() utils.Rc.Put(key, putVal, lastSecond) } //根据提问,获取信息 askUuid := utils.MD5(req.Ask) //chatMode, err := aimod.GetAiChatByAsk(askUuid) //if err != nil && err.Error() != utils.ErrNoRow() { // br.Msg = "获取数据失败!" // br.ErrMsg = "获取数据失败,GetAiChatByAsk,Err:" + err.Error() // return //} var assistantId, threadId string if req.AiChatTopicId > 0 { aiChatTopicObj := new(aimod.AiChatTopic) aiChatTopicObj.AiChatTopicId = req.AiChatTopicId topic, err := aiChatTopicObj.GetAiChatTopicById() if err != nil { if err.Error() == utils.ErrNoRow() { br.Msg = "获取数据失败!" br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error() return } br.Msg = "获取数据失败!" br.ErrMsg = "获取数据失败,GetAiChatTopicById,Err:" + err.Error() return } assistantId = topic.AssistantId threadId = topic.ThreadId } resp := new(aimod.ChatResp) var answer string //获取主题下的所有信息 //AiChatTopicId historyList, err := aimod.GetAiChatList(req.AiChatTopicId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取主题历史数据失败!" br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error() return } frList := make([]aimod.HistoryChat, 0) tmpFileIdList := make([]string, 0) // 历史消息 for _, v := range historyList { if v.OpenaiFileId != "" { tmpFileIdList = append(tmpFileIdList, v.OpenaiFileId) } else { historyFr := new(aimod.HistoryChat) historyFr.Ask = v.Ask historyFr.Answer = v.Answer historyFr.OpenaiFileId = tmpFileIdList frList = append(frList, *historyFr) tmpFileIdList = []string{} } } // 当前的消息 { frItem := new(aimod.HistoryChat) frItem.Ask = req.Ask frItem.Answer = "" frItem.OpenaiFileId = tmpFileIdList frList = append(frList, *frItem) } fileRetrieveResp, err := aiser.FileRetrieve(assistantId, threadId, req.Model, frList, req.OpenaiFileId) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "获取数据失败,FileRetrieve,Err:" + err.Error() return } if fileRetrieveResp != nil { if fileRetrieveResp.Ret == 200 { assistantId = fileRetrieveResp.Data.AssistantId threadId = fileRetrieveResp.Data.ThreadId answer = fileRetrieveResp.Data.Answer } else { br.Msg = "获取数据失败!" br.ErrMsg = fileRetrieveResp.Msg return } } if req.AiChatTopicId <= 0 { //新增 topic := new(aimod.AiChatTopic) topic.TopicName = req.Ask topic.SysUserId = this.SysUser.AdminId topic.SysUserRealName = this.SysUser.RealName topic.CreateTime = time.Now() topic.ModifyTime = time.Now() topic.AssistantId = assistantId topic.ThreadId = threadId topicId, err := aimod.AddAiChatTopic(topic) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "生成话题失败,Err:" + err.Error() return } chatItem := new(aimod.AiChat) chatItem.AiChatTopicId = int(topicId) chatItem.Ask = req.Ask chatItem.AskUuid = utils.MD5(req.Ask) chatItem.Answer = answer chatItem.Model = EnabledModelsForMap[req.Model] chatItem.SysUserId = this.SysUser.AdminId chatItem.SysUserRealName = this.SysUser.RealName chatItem.CreateTime = time.Now() chatItem.ModifyTime = time.Now() _, err = aimod.AddAiChat(chatItem) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "生成话题记录失败,Err:" + err.Error() return } req.AiChatTopicId = int(topicId) } else { chatItem := new(aimod.AiChat) chatItem.AiChatTopicId = req.AiChatTopicId chatItem.Ask = req.Ask chatItem.AskUuid = askUuid chatItem.Answer = answer chatItem.Model = EnabledModelsForMap[req.Model] chatItem.SysUserId = this.SysUser.AdminId chatItem.SysUserRealName = this.SysUser.RealName chatItem.CreateTime = time.Now() chatItem.ModifyTime = time.Now() _, err = aimod.AddAiChat(chatItem) if err != nil { br.Msg = "获取数据失败!" br.ErrMsg = "生成话题记录失败,Err:" + err.Error() return } //更新 assistantId,threadId aiChatTopicObj := new(aimod.AiChatTopic) updateParams := make(map[string]interface{}) updateParams["assistant_id"] = assistantId updateParams["thread_id"] = threadId updateParams["modify_time"] = time.Now() whereParam := make(map[string]interface{}) whereParam["ai_chat_topic_id"] = req.AiChatTopicId err = aiChatTopicObj.Update(updateParams, whereParam) if err != nil { br.Msg = "获取失败!" br.ErrMsg = "修改助手标识失败,Err:" + err.Error() return } } resp.Model = aimod.ModelViewMap[req.Model] resp.AiChatTopicId = req.AiChatTopicId resp.Ask = req.Ask resp.Answer = answer br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp return } var EnabledModelsForMap = map[string]string{ "Kimi": "moonshot-v1-32k", "GPT-4 Turbo": "gpt-4-1106-preview", }