Files
soul-yongping/soul-api/internal/handler/db_ckb_person_leads.go
卡若 5724fba877 feat: 小程序超级个体/个人资料/CKB获客;VIP列表展示过滤;管理端与API联调
- 超级个体:去掉首位特例;列表仅展示有头像且非微信默认昵称(vip.go)
- 个人资料:居中头像、低调联系方式、点头像优先走存客宝 lead(ckbLeadToken)
- 阅读页分享朋友圈复制与 toast 去重
- soul-api: miniprogram users 带 ckbLeadToken;其它 handler 与路由调整
- 脚本:content_upload、miniprogram 上传辅助等

Made-with: Cursor
2026-03-22 08:34:28 +08:00

103 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
})
}