package controllers import ( "WorldEpcho/src/config/e" database "WorldEpcho/src/datasource" "WorldEpcho/src/models" "WorldEpcho/src/service" "encoding/json" "fmt" "github.com/gin-gonic/gin" "net/http" "strconv" "strings" "time" ) // 定义英文-中文对照字典 /*var NpcRoleDetail = map[string]string{ "roleName": "角色名称", "introduction": "简介", "consumptionExpectations": "消费心理预期", "psychologicalTraits": "心理特征", "appearance": "外观", "personality": "性格", "decisionMakingStyle": "决策风格", "riskPreference": "风险偏好", "attitudeTowardsUsers": "对用户的态度", "educationLevel": "教育水平", "professionalBackground": "职业背景", "purpose": "目的性", "knownInformation": "已知信息", } */ //创建角色画像的请求体 type NpcRoleRequest struct { Name string `json:"name"` // 名称 Details Details `json:"details"` //详情 Gender string `json:"gender"` //性别 Tags string `json:"tags"` //世界标签集 RelatedWorlds string `json:"relatedWorlds"` //相关世界 UpdateTime int64 `json:"updateTime"` //更新时间 CreateTime int64 `json:"createTime"` //构造时间 ServiceProviderId string `json:"authId,omitempty"` // ServiceProviderId } // Detail 用于解析详细信息中的 JSON 字符串 type Details struct { RoleName string `json:"roleName"` //角色名称 Introduction Introduction `json:"introduction"` //简介 ConsumptionExpectations []string `json:"consumptionExpectations"` //消费心理预期 PsychologicalTraits []string `json:"psychologicalTraits"` //心理特征 Appearance string `json:"appearance"` //外观 Personality string `json:"personality"` //性格 DecisionMakingStyle string `json:"decisionMakingStyle"` //决策风格 RiskPreference string `json:"riskPreference"` //风险偏好 AttitudeTowardsUsers string `json:"attitudeTowardsUsers"` //对用户的态度 } //个人传记 Personal profile type Introduction struct { EducationLevel string `json:"educationLevel"` //教育水平 ProfessionalBackground string `json:"professionalBackground"` //职业背景 Purpose string `json:"purpose"` //目的性 KnownInformation string `json:"knownInformation"` //已知信息 } //创建Npc用户画像的接口 func CreateNpcUserPortrait(ctx *gin.Context) { var NpcRequest NpcRoleRequest if err := ctx.ShouldBindJSON(&NpcRequest); err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidParams, "data": nil, "message": "请求数据不正确"}) return } // 从请求头 Authorization 中提取令牌 tokenString := ctx.GetHeader("Token") if tokenString != "" { // 解析并验证 JWT 令牌 isValid, err := service.IsValidMiGuToken(tokenString) if err != nil || !isValid { ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效或已过期的令牌"}) return } } else { ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "请求头中无token,或未授权的token访问"}) return } if NpcRequest.Name == "" { ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "用户角色名称不能为空"}) return } if NpcRequest.ServiceProviderId == "" { ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "服务商id不能为空"}) return } sp, err := models.GetServiceProviderById(NpcRequest.ServiceProviderId) if err != nil || sp == nil { ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "根据服务商id查询服务商出错或服务商不存在", "error": err.Error()}) return } //可以访问的标签 // 创建一个空切片存储匹配的标签 matchingTags := []string{} // 分割字符串,得到单独的字符串 tagsSplit := strings.Split(NpcRequest.Tags, ",") for _, tagStr := range tagsSplit { //如果包含服务商可访问的世界标签,则遍历将包含的标签放入数组 // 检查每个用户标签是否被服务商允许 if ContainsString(sp.AccessibleTags, tagStr) { matchingTags = append(matchingTags, tagStr) } } // 如果没有任何匹配的标签,则返回错误信息 if len(matchingTags) == 0 { ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "不包含该服务商可访问的世界标签!"}) fmt.Println("不包含该服务商可访问的世界标签") return } // 序列化 Details 为 JSON 字符串 detailsJSON, err := json.Marshal(NpcRequest.Details) if err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "详情信息序列化失败"}) return } if string(detailsJSON) == "" { ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "用户详情信息不能为空"}) return } /* configData 英文键转换为中文 */ /* var data map[string]interface{} if err := json.Unmarshal([]byte(string(detailsJSON)), &data); err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "解析用户画像详细信息数据出错"}) return } // 转换键名 => 英文转中文 NpcRoleDetailTranslations := config.Conf.NpcRoleDetailTranslations translatedData := utils.TranslateKeysEnglishToChinese(NpcRoleDetailTranslations, data) translatedJSON, err := json.MarshalIndent(translatedData, "", " ") if err != nil { fmt.Println("Error marshalling JSON:", err) ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "解析用户画像详细信息数据出错"}) return } fmt.Println(" Details translatedJSON ==> ", string(translatedJSON)) */ // 创建一个空切片存储相关世界 relatedWorldIds := []int64{} // 分割字符串,得到单独的字符串 RelatedWorldIdsSplit := strings.Split(NpcRequest.RelatedWorlds, ",") for _, RelatedWorldId := range RelatedWorldIdsSplit { worldId, err := strconv.ParseInt(RelatedWorldId, 10, 64) if err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "相关世界ID类型转换错误"}) return } relatedWorldIds = append(relatedWorldIds, worldId) } //开启事务 session := database.Engine.NewSession() defer session.Close() if err := session.Begin(); err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "开启事务失败"}) return } //用户画像详情信息 // 将Details结构体转换为 JSON jsonData, err := json.Marshal(NpcRequest.Details) if err != nil { fmt.Println("Error:", err) return } npcUserRole := &models.NpcRole{ Name: NpcRequest.Name, Details: string(jsonData), Gender: NpcRequest.Gender, Tags: matchingTags, RelatedWorlds: relatedWorldIds, CreateTime: time.Now().Unix(), UpdateTime: time.Now().Unix(), } var newNpcRole *models.NpcRole if newNpcRole, err = models.CreateNpcRole(session, npcUserRole); err != nil { session.Rollback() ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "创建用户画像信息出错"}) return } if err := session.Commit(); err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "事务提交失败"}) return } ctx.JSON(http.StatusOK, gin.H{"code": e.SUCCESS, "data": gin.H{"newNpcRoleInfo": newNpcRole}, "message": "创建用户画像成功"}) } // 定义查询业务经理考核系统世界信息的请求参数的结构体 type NpcRoleRequestParams struct { WorldId int64 `json:"worldId"` Tags string `json:"tags"` ServiceProviderId string `json:"authId,omitempty"` // ServiceProviderId } // 查询业务经理考核相关的世界信息接口2 func QueryNpcRoleInfo(ctx *gin.Context) { var params NpcRoleRequestParams // 从请求体解析 JSON 参数 if err := ctx.BindJSON(¶ms); err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "参数解析错误"}) return } // 从请求头 Authorization 中提取令牌 tokenString := ctx.GetHeader("Token") if tokenString == "" { ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "请求头中无token,或未授权的token访问"}) return } // 解析并验证 JWT 令牌 isValid, err := service.IsValidMiGuToken(tokenString) if err != nil || !isValid { ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效或已过期的令牌"}) return } if params.ServiceProviderId == "" { ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "服务商id不能为空"}) return } sp, err := models.GetServiceProviderById(params.ServiceProviderId) if err != nil || sp == nil { ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "根据服务商id查询服务商出错或服务商不存在", "error": err.Error()}) return } //可以访问的标签 // 创建一个空切片存储匹配的标签 matchingTags := []string{} // 分割字符串,得到单独的字符串 tagsSplit := strings.Split(params.Tags, ",") for _, tagStr := range tagsSplit { //如果包含服务商可访问的世界标签,则遍历将包含的标签放入数组 // 检查每个用户标签是否被服务商允许 if ContainsString(sp.AccessibleTags, tagStr) { matchingTags = append(matchingTags, tagStr) } } // 如果没有任何匹配的标签,则返回错误信息 if len(matchingTags) == 0 { ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "不包含该服务商可访问的世界标签!"}) fmt.Println("不包含该服务商可访问的世界标签") return } /* worldInfo, err := models.FindWorlds2(params.WorldName, tagsArr) if err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "查询世界信息失败"}) return }*/ //开启事务 session := database.Engine.NewSession() defer session.Close() //延迟关闭session err1 := session.Begin() if err1 != nil { ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "开启事务失败!"}) fmt.Println("开启事务失败") return } //查询包含指定related_worlds ID的NPC角色数组 npcRoles, err := models.FindNpcRolesByWorldID(session, params.WorldId) if err != nil { ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "根据相关世界ID查询用户画像信息出错!"}) fmt.Println("根据相关世界ID查询用户画像信息出错") return } //提交事务 err = session.Commit() if err != nil { ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "提交事务失败"}) return } if npcRoles != nil { ctx.JSON(http.StatusOK, gin.H{ "code": e.SUCCESS, "data": gin.H{"npcRoles": npcRoles}, "message": "查询相关世界的用户画像信息成功", }) } else { ctx.JSON(http.StatusOK, gin.H{ "code": e.NotFound, "data": nil, "message": "未查相关世界的用户画像信息", }) } }