feat: MBTI头像与用户规则链路升级,三端页面与接口同步
Made-with: Cursor
This commit is contained in:
@@ -429,6 +429,7 @@ func CKBIndexLead(c *gin.Context) {
|
||||
Phone: phone,
|
||||
Wechat: wechatId,
|
||||
PersonName: personName,
|
||||
TargetMemberID: "",
|
||||
Source: source,
|
||||
Repeated: repeatedSubmit,
|
||||
LeadUserID: body.UserID,
|
||||
@@ -497,6 +498,7 @@ func CKBLead(c *gin.Context) {
|
||||
// 首页链接卡若:targetUserId 为空 → 用全局 getCkbLeadApiKey()
|
||||
leadKey := getCkbLeadApiKey()
|
||||
targetName := strings.TrimSpace(body.TargetNickname)
|
||||
targetMemberID := strings.TrimSpace(body.TargetMemberID)
|
||||
personTips := "" // Person 配置的获客成功提示,优先于默认文案
|
||||
if body.TargetUserID != "" {
|
||||
var p model.Person
|
||||
@@ -513,6 +515,11 @@ func CKBLead(c *gin.Context) {
|
||||
if targetName == "" {
|
||||
targetName = p.Name
|
||||
}
|
||||
if targetMemberID == "" {
|
||||
if p.UserID != nil {
|
||||
targetMemberID = strings.TrimSpace(*p.UserID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 去重:同一用户对同一目标人物只记录一次(不再限制时间间隔,允许对不同人物立即提交)
|
||||
@@ -611,6 +618,7 @@ func CKBLead(c *gin.Context) {
|
||||
Wechat: wechatId,
|
||||
PersonName: who,
|
||||
MemberName: strings.TrimSpace(body.TargetMemberName),
|
||||
TargetMemberID: targetMemberID,
|
||||
Source: source,
|
||||
Repeated: repeatedSubmit,
|
||||
LeadUserID: body.UserID,
|
||||
@@ -684,6 +692,7 @@ func CKBLead(c *gin.Context) {
|
||||
Wechat: wechatId,
|
||||
PersonName: who,
|
||||
MemberName: strings.TrimSpace(body.TargetMemberName),
|
||||
TargetMemberID: targetMemberID,
|
||||
Source: source,
|
||||
Repeated: repeatedSubmit,
|
||||
LeadUserID: body.UserID,
|
||||
@@ -720,6 +729,7 @@ type leadWebhookPayload struct {
|
||||
Wechat string
|
||||
PersonName string // 对接人(Person 表 name / targetNickname)
|
||||
MemberName string // 超级个体名称(targetMemberName)
|
||||
TargetMemberID string // 超级个体 userId,用于按人路由 webhook
|
||||
Source string // 技术来源标识
|
||||
Repeated bool
|
||||
LeadUserID string // 留资用户ID,用于查询行为轨迹
|
||||
@@ -750,31 +760,45 @@ var _webhookDedupCache = struct {
|
||||
m map[string]string
|
||||
}{m: make(map[string]string)}
|
||||
|
||||
func webhookShouldSkip(userId string) bool {
|
||||
if userId == "" {
|
||||
func webhookShouldSkip(userId string, targetMemberID string) bool {
|
||||
if userId == "" && targetMemberID == "" {
|
||||
return false
|
||||
}
|
||||
today := time.Now().Format("2006-01-02")
|
||||
key := strings.TrimSpace(userId) + "|" + strings.TrimSpace(targetMemberID)
|
||||
if key == "|" {
|
||||
return false
|
||||
}
|
||||
_webhookDedupCache.Lock()
|
||||
defer _webhookDedupCache.Unlock()
|
||||
if _webhookDedupCache.m[userId] == today {
|
||||
if _webhookDedupCache.m[key] == today {
|
||||
return true
|
||||
}
|
||||
_webhookDedupCache.m[userId] = today
|
||||
_webhookDedupCache.m[key] = today
|
||||
if len(_webhookDedupCache.m) > 10000 {
|
||||
_webhookDedupCache.m = map[string]string{userId: today}
|
||||
_webhookDedupCache.m = map[string]string{key: today}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func sendLeadWebhook(db *gorm.DB, p leadWebhookPayload) {
|
||||
if p.LeadUserID != "" && webhookShouldSkip(p.LeadUserID) {
|
||||
log.Printf("webhook: skip duplicate for user %s today", p.LeadUserID)
|
||||
return
|
||||
func loadLeadWebhookURL(db *gorm.DB, targetMemberID string) string {
|
||||
// 优先按超级个体 userId 映射(单人单群)
|
||||
targetMemberID = strings.TrimSpace(targetMemberID)
|
||||
if targetMemberID != "" {
|
||||
var mapCfg model.SystemConfig
|
||||
if err := db.Where("config_key = ?", superIndividualWebhookConfigKey).First(&mapCfg).Error; err == nil && len(mapCfg.ConfigValue) > 0 {
|
||||
var m map[string]string
|
||||
if json.Unmarshal(mapCfg.ConfigValue, &m) == nil {
|
||||
if u := strings.TrimSpace(m[targetMemberID]); u != "" && strings.HasPrefix(u, "http") {
|
||||
return u
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 回退全局获客 webhook
|
||||
var cfg model.SystemConfig
|
||||
if db.Where("config_key = ?", "ckb_lead_webhook_url").First(&cfg).Error != nil {
|
||||
return
|
||||
return ""
|
||||
}
|
||||
var webhookURL string
|
||||
if len(cfg.ConfigValue) > 0 {
|
||||
@@ -782,6 +806,18 @@ func sendLeadWebhook(db *gorm.DB, p leadWebhookPayload) {
|
||||
}
|
||||
webhookURL = strings.TrimSpace(webhookURL)
|
||||
if webhookURL == "" || !strings.HasPrefix(webhookURL, "http") {
|
||||
return ""
|
||||
}
|
||||
return webhookURL
|
||||
}
|
||||
|
||||
func sendLeadWebhook(db *gorm.DB, p leadWebhookPayload) {
|
||||
if p.LeadUserID != "" && webhookShouldSkip(p.LeadUserID, p.TargetMemberID) {
|
||||
log.Printf("webhook: skip duplicate for user %s today", p.LeadUserID)
|
||||
return
|
||||
}
|
||||
webhookURL := loadLeadWebhookURL(db, p.TargetMemberID)
|
||||
if webhookURL == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user