feat(distribution): 分销站点增加用户数量统计与用户信息展示模块

- 数据模型与迁移: 新增 000082 迁移在 users 表追加 distribution_site_id 并建索引,用户首次在分销站点注册/短信登录时自动绑定站点归属
- 分销管理接口: 新增 GET /admin/distribution/users 接口,聚合本站注册用户与下单客户,返回完整11位手机号、累计消费金额、订单数及来源标签
- 统计与大盘扩展: GET /admin/distribution/sites/:id/analytics 补全今日注册、累计用户、成交客户指标,主站分销商列表追加用户体量展示
- 分销后台前端: 新增「客户与用户」页面 (Users.tsx) 支持一键复制手机号与订单穿透,大盘 (Dashboard.tsx) 增加用户规模核心卡片
- 自动化测试与门禁: 新增 TestListDistributionUsersAndAnalytics 单元测试,通过全量 Go 后端集成测试及前后端构建检查
This commit is contained in:
yml2213
2026-10-10 14:58:33 +08:00
parent 6d34f86765
commit 4ea08e355b
17 changed files with 956 additions and 60 deletions
@@ -29,6 +29,8 @@ type SiteDTO struct {
AdminUsername string `json:"admin_username,omitempty"`
AdminNickname string `json:"admin_nickname,omitempty"`
MemberType string `json:"member_type,omitempty"`
UserCount int64 `json:"user_count"`
OrderUserCount int64 `json:"order_user_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
@@ -575,6 +577,9 @@ type DistributionAnalyticsDTO struct {
TodayProfitCent int64 `json:"today_profit_cent"`
MonthProfitCent int64 `json:"month_profit_cent"`
AvailableBalanceCent int64 `json:"available_balance_cent"`
TodayUserCount int64 `json:"today_user_count"`
TotalUserCount int64 `json:"total_user_count"`
TotalOrderUserCount int64 `json:"total_order_user_count"`
TrendDays []DistributionTrendPoint `json:"trend_days"`
}
@@ -618,3 +623,36 @@ type TestSiteSMSConfigRequest struct {
SignName *string `json:"sign_name"`
LoginTemplateCode *string `json:"login_template_code"`
}
// 分销站点客户/用户信息 DTO
type DistributionUserDTO struct {
ID uint64 `json:"id"`
Phone string `json:"phone"`
Nickname string `json:"nickname"`
AvatarURL string `json:"avatar_url"`
RealnameStatus string `json:"realname_status"`
Status string `json:"status"`
Source string `json:"source"` // register=本站注册, order=本站下单, both=注册并下单
OrderCount int64 `json:"order_count"`
TotalSpentCent int64 `json:"total_spent_cent"`
LastOrderAt *time.Time `json:"last_order_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
}
type DistributionUserPageDTO struct {
Items []DistributionUserDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalUsers int64 `json:"total_users"`
OrderUsers int64 `json:"order_users"`
}
type ListDistributionUsersQuery struct {
SiteID uint64 `form:"site_id"`
Keyword string `form:"keyword"`
Source string `form:"source"` // all / register / order
Page int `form:"page,default=1"`
PageSize int `form:"page_size,default=20"`
}