feat: 邀请关系列表增加邀请人累计统计

This commit is contained in:
yml2213
2026-10-19 17:52:54 +08:00
parent 27a6442c18
commit 51855a0e17
4 changed files with 214 additions and 13 deletions
@@ -922,21 +922,69 @@ func (r *Repository) ListAdminInvitations(ctx context.Context, query AdminInvita
return nil, 0, err
}
// 汇总本页邀请人名下的累计邀请人数(一次 IN 查询,避免逐行统计)。
inviterIDs := make([]uint64, 0, len(rows))
seenInviter := make(map[uint64]struct{}, len(rows))
for _, row := range rows {
if row.InviterID == 0 {
continue
}
if _, ok := seenInviter[row.InviterID]; ok {
continue
}
seenInviter[row.InviterID] = struct{}{}
inviterIDs = append(inviterIDs, row.InviterID)
}
type inviterStatRow struct {
InviterID uint64 `gorm:"column:inviter_id"`
TotalInvited int64 `gorm:"column:total_invited"`
ActiveInvited int64 `gorm:"column:active_invited"`
PendingInvited int64 `gorm:"column:pending_invited"`
InvalidInvited int64 `gorm:"column:invalid_invited"`
}
inviterStats := make(map[uint64]inviterStatRow, len(inviterIDs))
if len(inviterIDs) > 0 {
var statRows []inviterStatRow
statDB := r.db.WithContext(ctx).Model(&model.UserInvitation{}).
Select("inviter_id, COUNT(*) AS total_invited, "+
"SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) AS active_invited, "+
"SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending_invited, "+
"SUM(CASE WHEN status = 'invalid' THEN 1 ELSE 0 END) AS invalid_invited").
Where("inviter_id IN ?", inviterIDs).
Group("inviter_id")
// 分站后台只能看到本站范围内的累计数据,避免跨站泄露。
if query.DistributionSiteID != nil {
statDB = statDB.Where("distribution_site_id = ?", *query.DistributionSiteID)
}
if err := statDB.Scan(&statRows).Error; err != nil {
return nil, 0, err
}
for _, stat := range statRows {
inviterStats[stat.InviterID] = stat
}
}
list := make([]map[string]any, 0, len(rows))
for _, row := range rows {
stat := inviterStats[row.InviterID]
list = append(list, map[string]any{
"id": row.ID,
"inviter_id": row.InviterID,
"inviter_phone": row.InviterPhone,
"inviter_nickname": row.InviterNickname,
"invitee_id": row.InviteeID,
"invitee_phone": row.InviteePhone,
"invitee_nickname": row.InviteeNickname,
"distribution_site_id": row.DistributionSiteID,
"invite_code": row.InviteCode,
"status": row.Status,
"verified_at": row.VerifiedAt,
"created_at": row.CreatedAt,
"id": row.ID,
"inviter_id": row.InviterID,
"inviter_phone": row.InviterPhone,
"inviter_nickname": row.InviterNickname,
"inviter_total_invited": stat.TotalInvited,
"inviter_active_invited": stat.ActiveInvited,
"inviter_pending_invited": stat.PendingInvited,
"inviter_invalid_invited": stat.InvalidInvited,
"invitee_id": row.InviteeID,
"invitee_phone": row.InviteePhone,
"invitee_nickname": row.InviteeNickname,
"distribution_site_id": row.DistributionSiteID,
"invite_code": row.InviteCode,
"status": row.Status,
"verified_at": row.VerifiedAt,
"created_at": row.CreatedAt,
})
}
return list, total, nil