package service import ( "WorldEpcho/src/config" database "WorldEpcho/src/datasource" "WorldEpcho/src/models" "WorldEpcho/src/utils" "bytes" "encoding/json" "errors" "fmt" "io/ioutil" "log" "net/http" "strings" "time" ) var ( ColorReset = "\033[0m" ColorYellow = "\033[33m" ) // WorldCreateRequest 定义了创建世界时发送的请求体的结构体 type WorldCreateRequest struct { Auth string `json:"auth"` Name string `json:"name"` BgInfo string `json:"BgInfo"` UserInfo map[string]interface{} `json:"userInfo"` } // WorldCreateResponse 定义了创建世界时接受的响应体的结构体 type WorldCreateResponse struct { Code int `json:"code"` ISLIUid string `json:"ISLIUid"` WObj map[string]interface{} `json:"WObj"` ISLIU string `json:"ISLIU"` MessageStatusType string `json:"messageStatusType,omitempty"` // Optional field to indicate message type } // CreateWorld 是向指定的地址发送创建世界请求的函数 func NewWorld(url string, request WorldCreateRequest) (*WorldCreateResponse, error) { // 将请求体编码为 JSON requestBody, err := json.Marshal(request) if err != nil { return nil, fmt.Errorf("failed to encode request body: %w", err) } fmt.Printf(" 【 ****************** 发送请求... ==> new world IsLIUId, url:%s **************** 】", url) NewWorldStartTime := time.Now() // 创建 POST 请求 resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody)) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } defer resp.Body.Close() // 读取和解码响应体 var response WorldCreateResponse respBody, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response body: %w", err) } err = json.Unmarshal(respBody, &response) if err != nil { return nil, fmt.Errorf("failed to decode response body: %w", err) } fmt.Println(config.ColorBlue, "New world API Code:", response.Code, "code为1成功 0服务失效 3信息格式有误 4非法的服务商", config.ColorReset) if response.Code == 1 { NewWorldStartTimeDuration := time.Since(NewWorldStartTime) fmt.Println(" ================================================================== ") fmt.Printf(ColorYellow+"【 ****************** 请求成功响应... ==> new world IsLIUId, url:%s **************** 】"+ColorReset+"\n", url) log.Printf(" 【=== 响应成功耗时 : %s\n ===】", NewWorldStartTimeDuration.String()) if len(response.WObj) == 0 && strings.Contains(response.ISLIU, "【任务提示】") { response.MessageStatusType = "prologue" } } return &response, nil } // 创建虚拟世界控制器 /* func CreateVirtualWorldHandler(uid int64, name, BgInfo, userInfo string) (*WorldCreateResponse, error) { //获取服务商凭证 auth := config.Conf.SoulAuth // 将JSON字符串转换为字节切片 fmt.Println("userInfo: ", userInfo) jsonDataBytes := []byte(userInfo) //fmt.Println("jsonDataBytes: ", jsonDataBytes) // 定义map接收解析后的数据 var UserInfo map[string]interface{} // 解析JSON数据到map if err := json.Unmarshal(jsonDataBytes, &UserInfo); err != nil { fmt.Println("用户json信息解析失败", err) return nil, err } var worldCreateRequest = WorldCreateRequest{ Auth: auth, Name: name, BgInfo: BgInfo, UserInfo: UserInfo, } fmt.Println("创建世界的参数请求体:", worldCreateRequest) //请求url quest_url := config.Conf.SoulUrl + "/world/new" //quest_url := "http://192.168.2.239:13679/world/new" response, err := NewWorld(quest_url, worldCreateRequest) if err != nil { fmt.Println("Error creating world:", err) return nil, err } //根据世界名称查询世界对象是否存在 wordInfo, err := models.GetWorldInfoByName(name) if err != nil { return nil, errors.New("根据世界名称查询世界对象出错") } // 声明临时变量保存世界id var worldId int64 if wordInfo == nil { //在世界信息表中创建世界的相关信息 // 创建一个新的世界信息实例 newWorld := models.WorldInfo{ Name: name, Background: BgInfo, CreatedAt: time.Now().Unix(), } wId, err := models.AddWorldInfo(&newWorld) if err != nil { return nil, errors.New("创建世界信息出错") } worldId = wId } else { worldId = wordInfo.ID } //根据用户id和世界名称查询会话是否存在 wc, conver_exist, err := models.GetWorldConversationByUidAndWorldName(uid, name) if err != nil { return nil, errors.New("根据用户id和世界名称查询会话出错") } //byName, err := models.GetWorldInfoByName(name) if response.Code == 1 { //如果会话不存在,创建对应的世界流会话 if !conver_exist { //创建世界成功,保存相关信息到数据库 // 创建一个世界会话的实例 title := "id为" + utils.Strval(uid) + "的用户在" + name + "的世界中聊天" newWorldconversation := models.WorldConversation{ Uid: uid, IsLiuId: response.ISLIUid, WorldId: worldId, WorldName: name, Title: title, BgInfo: BgInfo, UserInfo: userInfo, } // 调用AddWorld函数添加新的世界 err = models.AddWorldConversation(newWorldconversation) if err != nil { log.Fatal("添加世界流会话失败:", err) return nil, errors.New("添加世界流会话失败") } } else { //如果已经存在世界流会话了,则更新意识流id wc.IsLiuId = response.ISLIUid err := models.UpdateWorldConversation(wc) if err != nil { return nil, errors.New("更新世界意识流id失败") } } //c.JSON(http.StatusOK, gin.H{"code": 1, "message": "创建虚拟世界成功"}) } // 打印响应结果 fmt.Println("world Response Code:", response.Code) fmt.Println("world ISLIUid:", response.ISLIUid) fmt.Println("world WObj:", response.WObj) fmt.Println("world ISLIU:", response.ISLIU) return response, nil } */ func CreateVirtualWorldHandler(uid int64, name, BgInfo, userInfo string) (*WorldCreateResponse, *models.WorldConversation, error) { //获取服务商凭证 auth := config.Conf.SoulAuth // 将JSON字符串转换为字节切片 fmt.Println("userInfo: ", userInfo) jsonDataBytes := []byte(userInfo) //fmt.Println("jsonDataBytes: ", jsonDataBytes) // 定义map接收解析后的数据 var UserInfo map[string]interface{} // 解析JSON数据到map if err := json.Unmarshal(jsonDataBytes, &UserInfo); err != nil { fmt.Println("用户json信息解析失败", err) return nil, nil, err } //根据世界名称查询世界对象是否存在 wordInfo, err := models.GetWorldInfoByName(name) if err != nil { return nil, nil, errors.New("根据世界名称查询世界对象出错") } var worldCreateRequest = WorldCreateRequest{ Auth: auth, BgInfo: BgInfo, UserInfo: UserInfo, } if ContainsString(wordInfo.Tags, "业务经理考核系统") { worldCreateRequest.Name = "定制考核" } else { worldCreateRequest.Name = name } fmt.Println("创建世界的参数请求体:", worldCreateRequest) //请求url quest_url := config.Conf.SoulUrl + "/world/new" //quest_url := "http://192.168.2.239:13679/world/new" response, err := NewWorld(quest_url, worldCreateRequest) if err != nil { fmt.Println("Error creating world:", err) return nil, nil, err } //开启事务 session := database.Engine.NewSession() defer session.Close() //延迟关闭session err = session.Begin() if err != nil { fmt.Println("开启事务失败") return nil, nil, errors.New("开启事务失败") } // 声明临时变量保存世界id var worldId int64 if wordInfo == nil { //在世界信息表中创建世界的相关信息 // 创建一个新的世界信息实例 newWorld := models.WorldInfo{ Name: name, Background: BgInfo, CreatedAt: time.Now().Unix(), } wId, err := models.AddWorldInfo(session, &newWorld) if err != nil { return nil, nil, errors.New("创建世界信息出错") } worldId = wId } else { worldId = wordInfo.ID } //根据用户id和世界名称查询会话是否存在 wc, conver_exist, err := models.GetWorldConversationByUidAndWorldName_Tx(session, uid, name) if err != nil { return nil, nil, errors.New("根据用户id和世界名称查询会话出错") } var newWorldconversation models.WorldConversation //byName, err := models.GetWorldInfoByName(name) if response.Code == 1 { //如果会话不存在,创建对应的世界流会话 if !conver_exist { //创建世界成功,保存相关信息到数据库 // 创建一个世界会话的实例 title := "id为" + utils.Strval(uid) + "的用户在" + name + "的世界中聊天" newWorldconversation.Uid = uid newWorldconversation.IsLiuId = response.ISLIUid newWorldconversation.WorldId = worldId newWorldconversation.WorldName = name newWorldconversation.Title = title newWorldconversation.BgInfo = BgInfo newWorldconversation.UserInfo = userInfo // 调用AddWorld函数添加新的世界 err = models.AddWorldConversation(session, &newWorldconversation) if err != nil { fmt.Println("添加世界流会话失败:", err) return nil, nil, errors.New("添加世界流会话失败") } //return response, &newWorldconversation, nil } else { //如果已经存在世界流会话了,则更新意识流id wc.IsLiuId = response.ISLIUid newWorldconversation = *wc // 将已存在的会话对象赋值给newWorldconversation err := models.UpdateWorldConversation(session, wc) if err != nil { return nil, nil, errors.New("更新世界意识流id失败") } } //c.JSON(http.StatusOK, gin.H{"code": 1, "message": "创建虚拟世界成功"}) } //提交事务 err = session.Commit() if err != nil { //ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建数字人失败! "}) return nil, nil, nil } // 打印响应结果 fmt.Println("world Response Code:", response.Code) fmt.Println("world ISLIUid:", response.ISLIUid) fmt.Println("world WObj:", response.WObj) fmt.Println("world ISLIU:", response.ISLIU) fmt.Println("world MessageStatusType:", response.MessageStatusType) return response, &newWorldconversation, nil } func MiGuCreateVirtualWorldHandler(uid, wid int64, BgInfo, userInfo string) (*WorldCreateResponse, *models.WorldConversation, error) { // 创建世界开始时间 //createWorldStartTime := time.Now() //fmt.Println(config.ColorGreen, "=================【 开始请求模型端创建世界接口.... 】 =================", config.ColorReset) //获取服务商凭证 auth := config.Conf.SoulAuth // 将JSON字符串转换为字节切片 fmt.Println("userInfo: ", userInfo) jsonDataBytes := []byte(userInfo) //fmt.Println("jsonDataBytes: ", jsonDataBytes) // 定义map接收解析后的数据 var UserInfo map[string]interface{} // 解析JSON数据到map if err := json.Unmarshal(jsonDataBytes, &UserInfo); err != nil { fmt.Println("用户json信息解析失败", err) return nil, nil, err } var worldName string //根据世界名称查询世界对象是否存在 wordInfo, _, err := models.GetWorldInfoById(wid) if err != nil { return nil, nil, errors.New("根据世界名称查询世界对象出错") } if wordInfo == nil { return nil, nil, errors.New("世界信息不存在") } worldName = wordInfo.Name var worldCreateRequest = WorldCreateRequest{ Auth: auth, BgInfo: BgInfo, UserInfo: UserInfo, } if ContainsString(wordInfo.Tags, "业务经理考核系统") { worldCreateRequest.Name = "定制考核" } else { worldCreateRequest.Name = worldName } fmt.Println("创建世界的参数请求体:", worldCreateRequest) //请求url quest_url := config.Conf.SoulUrl + "/world/new" //quest_url := "http://192.168.2.239:13679/world/new" //fmt.Println(config.ColorGreen, "=================【 开始请求模型端创建世界接口.... 】 =================", config.ColorReset) //startNewWorldAPITime := time.Now() // 记录 startNewWorldAPITime 调用模型服务端接口执行创建世界前的时间 response, err := NewWorld(quest_url, worldCreateRequest) if err != nil { fmt.Println("Error creating world:", err) return nil, nil, err } //fmt.Println(config.ColorGreen, "=================【 请求模型端创建世界接口...结束. 】 =================", config.ColorReset) //NewWorldAPIDuration := time.Since(createWorldStartTime) // 计算 NewWorld 函数执行时间 // 计算整个函数执行的总时间 // log.Printf("【 === 调用模型端创建世界接口,耗费时间: %s\n ==】", NewWorldAPIDuration.String()) //开启事务 session := database.Engine.NewSession() defer session.Close() //延迟关闭session err = session.Begin() if err != nil { fmt.Println("开启事务失败") return nil, nil, errors.New("开启事务失败") } // 声明临时变量保存世界id var worldId int64 if wordInfo == nil { //在世界信息表中创建世界的相关信息 // 创建一个新的世界信息实例 newWorld := models.WorldInfo{ Name: worldName, Background: BgInfo, CreatedAt: time.Now().Unix(), } wId, err := models.AddWorldInfo(session, &newWorld) if err != nil { return nil, nil, errors.New("创建世界信息出错") } worldId = wId } else { worldId = wordInfo.ID } //根据用户id和世界名称查询会话是否存在 wc, conver_exist, err := models.GetWorldConversationByUidAndWorldId_Tx(session, uid, wid) if err != nil { return nil, nil, errors.New("根据用户id和世界名称查询会话出错") } var newWorldconversation models.WorldConversation //byName, err := models.GetWorldInfoByName(name) //responseNewWorldAPI_Time1 := time.Now() // 记录调用模型端创建世界响应时间 if response.Code == 1 { //responseCode1Time1 := time.Since(createWorldStartTime) //fmt.Println(" ================================================================== ") //log.Printf(" 【=== 调用模型端创建世界接口,响应 response.Code == 1 耗费时间: %s\n ===】", responseCode1Time1.String()) //如果会话不存在,创建对应的世界流会话 //responseNewWorldAPITime := time.Now() if !conver_exist { //创建世界成功,保存相关信息到数据库 // 创建一个世界会话的实例 title := "id为" + utils.Strval(uid) + "的用户在" + worldName + "的世界中聊天" newWorldconversation.Uid = uid newWorldconversation.IsLiuId = response.ISLIUid newWorldconversation.WorldId = worldId newWorldconversation.WorldName = worldName newWorldconversation.Title = title newWorldconversation.BgInfo = BgInfo newWorldconversation.UserInfo = userInfo // 调用AddWorld函数添加新的世界 err = models.AddWorldConversation(session, &newWorldconversation) if err != nil { fmt.Println("添加世界流会话失败:", err) return nil, nil, errors.New("添加世界流会话失败") } //return response, &newWorldconversation, nil } else { //如果已经存在世界流会话了,则更新意识流id wc.IsLiuId = response.ISLIUid newWorldconversation = *wc // 将已存在的会话对象赋值给newWorldconversation err := models.UpdateWorldConversation(session, wc) if err != nil { return nil, nil, errors.New("更新世界意识流id失败") } } // 计算整个函数执行的总时间 //responseCode1Time2 := time.Since(responseNewWorldAPITime) //log.Printf(" 【 ==== 调用模型端创建世界接口,响应 response.Code = 1 后更新数据库 耗费时间: %s\n ===】", responseCode1Time2.String()) //c.JSON(http.StatusOK, gin.H{"code": 1, "message": "创建虚拟世界成功"}) } //提交事务 err = session.Commit() if err != nil { //ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建数字人失败! "}) return nil, nil, nil } // 打印响应结果 fmt.Println("world Response Code:", response.Code) fmt.Println("world ISLIUid:", response.ISLIUid) fmt.Println("world WObj:", response.WObj) fmt.Println("world ISLIU:", response.ISLIU) fmt.Println("world MessageStatusType:", response.MessageStatusType) return response, &newWorldconversation, nil } // ContainsString 检查字符串数组是否包含一个特定的字符串 func ContainsString(slice []string, item string) bool { for _, elem := range slice { if elem == item { return true } } return false }