package handler import ( "net/http" "strconv" "strings" "soul-api/internal/database" "soul-api/internal/model" "github.com/gin-gonic/gin" ) // DBCKBPersonLeads GET /api/db/ckb-person-leads // - 不带 token:返回每个 Person 的获客数(基于 ckb_lead_records.target_person_id) // - 带 token:返回该 Person 的获客明细(分页) func DBCKBPersonLeads(c *gin.Context) { db := database.DB() token := strings.TrimSpace(c.Query("token")) // 1) 汇总:每个人物的获客数(按 user_id 去重,同一用户多次留资只算 1 人) if token == "" { type Row struct { Token string `json:"token"` Total int64 `json:"total"` } var rows []Row if err := db.Raw(` SELECT p.token AS token, COUNT(DISTINCT l.user_id) AS total FROM persons p LEFT JOIN ckb_lead_records l ON l.target_person_id = p.person_id GROUP BY p.token `).Scan(&rows).Error; err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"success": true, "byPerson": rows}) return } // 2) 明细:某个人物的获客列表 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 20 } var person model.Person // token 是管理端/小程序统一引用的主键;兜底允许传 personId(便于排查/手工调用) if err := db.Where("token = ? OR person_id = ?", token, token).First(&person).Error; err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "error": "未找到人物"}) return } var total int64 db.Model(&model.CkbLeadRecord{}).Where("target_person_id = ?", person.PersonID). Select("COUNT(DISTINCT user_id)").Scan(&total) var records []model.CkbLeadRecord if err := db.Raw(` SELECT l.* FROM ckb_lead_records l INNER JOIN ( SELECT user_id, MAX(created_at) AS max_at FROM ckb_lead_records WHERE target_person_id = ? GROUP BY user_id ) latest ON l.user_id = latest.user_id AND l.created_at = latest.max_at WHERE l.target_person_id = ? ORDER BY l.created_at DESC LIMIT ? OFFSET ? `, person.PersonID, person.PersonID, pageSize, (page-1)*pageSize).Scan(&records).Error; err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()}) return } out := make([]gin.H, 0, len(records)) for _, r := range records { out = append(out, gin.H{ "id": r.ID, "userId": r.UserID, "nickname": r.Nickname, "phone": r.Phone, "wechatId": r.WechatID, "name": r.Name, "source": r.Source, "createdAt": r.CreatedAt, }) } c.JSON(http.StatusOK, gin.H{ "success": true, "records": out, "total": total, "page": page, "pageSize": pageSize, "personName": person.Name, }) }