package handler import ( "bytes" "crypto/md5" "encoding/hex" "encoding/json" "io" "net/http" "sort" "strconv" "time" "github.com/gin-gonic/gin" ) const ckbAPIKey = "fyngh-ecy9h-qkdae-epwd5-rz6kd" const ckbAPIURL = "https://ckbapi.quwanzhi.com/v1/api/scenarios" var ckbSourceMap = map[string]string{"team": "团队招募", "investor": "资源对接", "mentor": "导师顾问", "partner": "创业合伙"} var ckbTagsMap = map[string]string{"team": "切片团队,团队招募", "investor": "资源对接,资源群", "mentor": "导师顾问,咨询服务", "partner": "创业合伙,创业伙伴"} func ckbSign(params map[string]interface{}, apiKey string) string { keys := make([]string, 0, len(params)) for k := range params { if k == "sign" || k == "apiKey" || k == "portrait" { continue } v := params[k] if v == nil || v == "" { continue } keys = append(keys, k) } sort.Strings(keys) var concat string for _, k := range keys { switch v := params[k].(type) { case string: concat += v case float64: concat += strconv.FormatFloat(v, 'f', -1, 64) case int: concat += strconv.Itoa(v) default: concat += "" } } h := md5.Sum([]byte(concat)) first := hex.EncodeToString(h[:]) h2 := md5.Sum([]byte(first + apiKey)) return hex.EncodeToString(h2[:]) } // CKBJoin POST /api/ckb/join func CKBJoin(c *gin.Context) { var body struct { Type string `json:"type" binding:"required"` Phone string `json:"phone"` Wechat string `json:"wechat"` Name string `json:"name"` UserID string `json:"userId"` Remark string `json:"remark"` } if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "请提供手机号或微信号"}) return } if body.Phone == "" && body.Wechat == "" { c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "请提供手机号或微信号"}) return } if body.Type != "team" && body.Type != "investor" && body.Type != "mentor" && body.Type != "partner" { c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "无效的加入类型"}) return } ts := time.Now().Unix() params := map[string]interface{}{ "timestamp": ts, "source": "创业实验-" + ckbSourceMap[body.Type], "tags": ckbTagsMap[body.Type], "siteTags": "创业实验APP", "remark": body.Remark, } if body.Remark == "" { params["remark"] = "用户通过创业实验APP申请" + ckbSourceMap[body.Type] } if body.Phone != "" { params["phone"] = body.Phone } if body.Wechat != "" { params["wechatId"] = body.Wechat } if body.Name != "" { params["name"] = body.Name } params["apiKey"] = ckbAPIKey params["sign"] = ckbSign(params, ckbAPIKey) params["portrait"] = map[string]interface{}{ "type": 4, "source": 0, "sourceData": map[string]interface{}{ "joinType": body.Type, "joinLabel": ckbSourceMap[body.Type], "userId": body.UserID, "device": "webapp", "timestamp": time.Now().Format(time.RFC3339), }, "remark": ckbSourceMap[body.Type] + "申请", "uniqueId": "soul_" + body.Phone + body.Wechat + strconv.FormatInt(ts, 10), } raw, _ := json.Marshal(params) resp, err := http.Post(ckbAPIURL, "application/json", bytes.NewReader(raw)) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "服务器错误,请稍后重试"}) return } defer resp.Body.Close() b, _ := io.ReadAll(resp.Body) var result struct { Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data"` } _ = json.Unmarshal(b, &result) if result.Code == 200 { msg := "成功加入" + ckbSourceMap[body.Type] if result.Message == "已存在" { msg = "您已加入,我们会尽快联系您" } c.JSON(http.StatusOK, gin.H{"success": true, "message": msg, "data": result.Data}) return } c.JSON(http.StatusOK, gin.H{"success": false, "message": result.Message}) } // CKBMatch POST /api/ckb/match func CKBMatch(c *gin.Context) { var body struct { MatchType string `json:"matchType"` Phone string `json:"phone"` Wechat string `json:"wechat"` UserID string `json:"userId"` Nickname string `json:"nickname"` MatchedUser interface{} `json:"matchedUser"` } _ = c.ShouldBindJSON(&body) if body.Phone == "" && body.Wechat == "" { c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "请提供手机号或微信号"}) return } ts := time.Now().Unix() label := ckbSourceMap[body.MatchType] if label == "" { label = "创业合伙" } params := map[string]interface{}{ "timestamp": ts, "source": "创业实验-找伙伴匹配", "tags": "找伙伴," + label, "siteTags": "创业实验APP,匹配用户", "remark": "用户发起" + label + "匹配", } if body.Phone != "" { params["phone"] = body.Phone } if body.Wechat != "" { params["wechatId"] = body.Wechat } if body.Nickname != "" { params["name"] = body.Nickname } params["apiKey"] = ckbAPIKey params["sign"] = ckbSign(params, ckbAPIKey) params["portrait"] = map[string]interface{}{ "type": 4, "source": 0, "sourceData": map[string]interface{}{ "action": "match", "matchType": body.MatchType, "matchLabel": label, "userId": body.UserID, "device": "webapp", "timestamp": time.Now().Format(time.RFC3339), }, "remark": "找伙伴匹配-" + label, "uniqueId": "soul_match_" + body.Phone + body.Wechat + strconv.FormatInt(ts, 10), } raw, _ := json.Marshal(params) resp, err := http.Post(ckbAPIURL, "application/json", bytes.NewReader(raw)) if err != nil { c.JSON(http.StatusOK, gin.H{"success": true, "message": "匹配成功"}) return } defer resp.Body.Close() b, _ := io.ReadAll(resp.Body) var result struct { Code int `json:"code"` Message string `json:"message"` } _ = json.Unmarshal(b, &result) if result.Code == 200 { c.JSON(http.StatusOK, gin.H{"success": true, "message": "匹配记录已上报", "data": nil}) return } c.JSON(http.StatusOK, gin.H{"success": true, "message": "匹配成功"}) } // CKBSync GET/POST /api/ckb/sync func CKBSync(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"success": true}) }