运行Go Gin服务报panic: reflect.StructOf: duplicate field DeveloperID如何解决
问题解决方法
第一步:修复启动panic报错
报错的根本原因是多对多关联配置错误:你在Developer模型里错误定义了自关联的多对多关系,GORM生成中间表developer_teams时会尝试创建两个DeveloperID字段作为外键,导致字段重复冲突。
正确的多对多关系应该是Developer和Team双向关联,修改两个模型的代码即可:
修改/models/developer.go
package models import "gorm.io/gorm" type Developer struct { gorm.Model ID uint `json:"id" gorm:"primary_key"` Full_name string `json:"full_name"` Email string `json:"email"` Mobile string `json:"mobile"` // 替换原来自关联的字段,改为和Team的多对多关联 Teams []Team `gorm:"many2many:developer_teams"` }
修改/models/team.go
package models import "gorm.io/gorm" type Team struct { gorm.Model ID uint `json:"id" gorm:"primary_key"` Name string `json:"name"` Dept string `json:"dept_name"` Messages []Message // 新增和Developer的多对多关联 Developers []Developer `gorm:"many2many:developer_teams"` }
修改完这两个文件后,服务启动的panic问题就会解决。
第二步:修复接口逻辑,实现预期返回
你当前的接口查询逻辑存在两处问题,需要调整才能符合返回要求:
- Raw查询没有传入
TeamID参数,也没有把结果Scan到字符串切片中,直接返回GORM查询对象不符合格式要求 - 生成的UUID需要转为字符串格式,时间也可以格式化匹配你预期的输出样式
修改/controllers/trigger_controller.go的Notification函数:
func Notification(c *gin.Context) { var input MessageInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } u1, err := uuid.NewV4() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "生成唯一标识失败"}) return } // 保存消息记录 message := models.Message{TeamID: input.TeamID, Title: input.Title, Content: input.Content} models.DB.Create(&message) // 查询指定团队下所有开发者手机号 var mobiles []string err = models.DB.Raw(`SELECT "developers"."mobile" FROM "developers" INNER JOIN "developer_teams" ON "developers"."id" = "developer_teams"."developer_id" WHERE "developer_teams"."team_id" = ?`, input.TeamID).Scan(&mobiles).Error if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "查询手机号失败"}) return } // 查询指定团队下所有开发者邮箱 var emails []string err = models.DB.Raw(`SELECT "developers"."email" FROM "developers" INNER JOIN "developer_teams" ON "developers"."id" = "developer_teams"."developer_id" WHERE "developer_teams"."team_id" = ?`, input.TeamID).Scan(&emails).Error if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "查询邮箱失败"}) return } c.JSON(http.StatusOK, gin.H{ "team_id": input.TeamID, "sms": gin.H{ "id": u1.String(), "mobiles": mobiles, "content": input.Content, "sent_at": time.Now().Format("15:04:05 MST 2006"), }, "email": gin.H{ "id": u1.String(), "emails": emails, "title": input.Title, "content": input.Content, "sent_at": time.Now().Format("15:04:05 MST 2006"), }, }, ) }
内容的提问来源于stack exchange,提问作者Lazlo
相关产品推荐
相关产品推荐

