diff --git a/soul-api/internal/handler/admin_shensheshou.go b/soul-api/internal/handler/admin_shensheshou.go index 24091e72..efa6c665 100644 --- a/soul-api/internal/handler/admin_shensheshou.go +++ b/soul-api/internal/handler/admin_shensheshou.go @@ -139,6 +139,105 @@ func AdminShensheShouIngest(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"success": true, "data": result["data"]}) } +// AdminShensheShouEnrich POST /api/admin/shensheshou/enrich — 查询并回填用户基础信息 +func AdminShensheShouEnrich(c *gin.Context) { + if sssAPIKey() == "" { + c.JSON(http.StatusOK, gin.H{"success": false, "error": "神射手 API Key 未配置"}) + return + } + + var body struct { + UserID string `json:"userId" binding:"required"` + Phone string `json:"phone"` + OpenID string `json:"openId"` + WechatID string `json:"wechatId"` + Address string `json:"address"` + } + if err := c.ShouldBindJSON(&body); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "参数错误"}) + return + } + + if body.Phone == "" && body.OpenID == "" && body.WechatID == "" { + c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "至少提供手机号、OpenID 或微信号之一"}) + return + } + + // 查询神射手 + queryURL := sssBaseURL() + "?endpoint=user" + if body.Phone != "" { + queryURL += "&phone=" + body.Phone + } + + sssResult, err := sssDoRequest(http.MethodGet, queryURL, nil) + if err != nil { + c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()}) + return + } + + var sssData map[string]interface{} + if d, ok := sssResult["data"].(map[string]interface{}); ok { + sssData = d + } + + // 将神射手数据回填到用户 tags + if sssData != nil { + db := database.DB() + updates := make(map[string]interface{}) + + // 自动合并标签 + if tags, ok := sssData["tags"].([]interface{}); ok && len(tags) > 0 { + tagStrs := make([]string, 0, len(tags)) + for _, t := range tags { + if s, ok := t.(string); ok { + tagStrs = append(tagStrs, s) + } + } + if len(tagStrs) > 0 { + tagsJSON, _ := json.Marshal(tagStrs) + updates["ckb_tags"] = string(tagsJSON) + } + } + + if len(updates) > 0 { + db.Table("users").Where("id = ?", body.UserID).Updates(updates) + } + } + + c.JSON(http.StatusOK, gin.H{"success": true, "data": sssData}) +} + +// AdminShensheShouAutoTag POST /api/admin/shensheshou/auto-tag — 基于行为自动打标(内部调用) +func AdminShensheShouAutoTag(userID string, phone string) { + if sssAPIKey() == "" || phone == "" { + return + } + go func() { + queryURL := sssBaseURL() + "?endpoint=user&phone=" + phone + result, err := sssDoRequest(http.MethodGet, queryURL, nil) + if err != nil || result == nil { + return + } + data, ok := result["data"].(map[string]interface{}) + if !ok { + return + } + tags, ok := data["tags"].([]interface{}) + if !ok || len(tags) == 0 { + return + } + tagStrs := make([]string, 0, len(tags)) + for _, t := range tags { + if s, ok := t.(string); ok { + tagStrs = append(tagStrs, s) + } + } + tagsJSON, _ := json.Marshal(tagStrs) + database.DB().Table("users").Where("id = ?", userID). + Updates(map[string]interface{}{"ckb_tags": string(tagsJSON)}) + }() +} + // AdminShensheShouBatchQuery POST /api/admin/shensheshou/batch — 批量查询 func AdminShensheShouBatchQuery(c *gin.Context) { if sssAPIKey() == "" {