fix: Campaign Create 400 + Reports 500 + 种子数据补全

修复:
- campaign_handler.go: Campaign创建JSON解析报VALIDATION_ERROR
- analytics_query_helpers.go: Reports标签/团队维度500(SQL query)
- bootstrap.go: 补充Campaign种子数据确保测试环境完整
This commit is contained in:
Rogee
2026-07-27 22:01:50 +08:00
parent 1c6b8c661c
commit 05c5752a2b
3 changed files with 26 additions and 8 deletions
@@ -78,15 +78,27 @@ func (h *CampaignHandler) Create(c *gin.Context) {
return
}
// Chatwoot: params.require(:campaign) → request body must be {"campaign": {...}}
// Accept both wrapped {"campaign": {...}} (Chatwoot style) and flat {...} payloads.
// The frontend sends flat payload, so we prefer that format.
var req service.CreateCampaignRequest
var wrapper struct {
Campaign service.CreateCampaignRequest `json:"campaign"`
}
if err := c.ShouldBindJSON(&wrapper); err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
rawBody, err := c.GetRawData()
if err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "cannot read request body")
return
}
req := wrapper.Campaign
// Try wrapped format first (Chatwoot style)
if err := json.Unmarshal(rawBody, &wrapper); err == nil && wrapper.Campaign.Title != "" {
req = wrapper.Campaign
} else {
// Fall back to flat format (GoChat style - what the frontend sends)
if err := json.Unmarshal(rawBody, &req); err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
return
}
}
campaign, svcErr := h.svc.Create(c.Request.Context(), accountID, req)
if svcErr != nil {