feat(adtracking): 新增推广链接追踪与数据大盘,支持自定义短码、注册与下单归因及二维码物料生成

1. 数据库新增 000064_ad_tracking.sql 迁移,创建 ad_tracking_links 和 ad_tracking_clicks 表,并在 users、rental_orders 增加归因字段
2. 后端新增 adtracking 模块,挂载 GET /r/:code 302 智能重定向、点击流水异步记录、转化率/GMV聚合统计及管理接口
3. 用户认证 (auth) 与订单创建 (order) 链路贯通,实现注册用户与订单成交推广短码全链路归因
4. 前端管理后台左侧新增【推广追踪】目录,支持大盘指标总览、推广链接 CRUD、状态启停、一键复制短链及二维码下载 (PNG)
This commit is contained in:
yml2213
2026-09-10 11:05:47 +08:00
parent 33ee8408e9
commit 2b11d70ebe
25 changed files with 2304 additions and 36 deletions
+4 -4
View File
@@ -157,7 +157,7 @@ func (s *Service) SendSMSCode(ctx context.Context, phone string, captchaID strin
return nil
}
func (s *Service) LoginWithSMS(ctx context.Context, phone string, code string) (LoginResult, error) {
func (s *Service) LoginWithSMS(ctx context.Context, phone string, code string, trackCode ...string) (LoginResult, error) {
if s.redis == nil || s.users == nil {
return LoginResult{}, ErrDependencyUnavailable
}
@@ -173,7 +173,7 @@ func (s *Service) LoginWithSMS(ctx context.Context, phone string, code string) (
return LoginResult{}, err
}
user, err := s.users.FindOrCreateByPhone(ctx, phone)
user, err := s.users.FindOrCreateByPhone(ctx, phone, trackCode...)
if err != nil {
return LoginResult{}, err
}
@@ -342,7 +342,7 @@ func (s *Service) ResetPassword(ctx context.Context, phone, code, newPassword st
return nil
}
func (s *Service) RegisterWithPassword(ctx context.Context, phone, code, password string) (LoginResult, error) {
func (s *Service) RegisterWithPassword(ctx context.Context, phone, code, password string, trackCode ...string) (LoginResult, error) {
if s.redis == nil || s.users == nil {
return LoginResult{}, ErrDependencyUnavailable
}
@@ -375,7 +375,7 @@ func (s *Service) RegisterWithPassword(ctx context.Context, phone, code, passwor
return LoginResult{}, err
}
user, err := s.users.RegisterWithPassword(ctx, phone, string(hash))
user, err := s.users.RegisterWithPassword(ctx, phone, string(hash), trackCode...)
if err != nil {
// 并发场景下仍可能因唯一索引冲突,统一按"已注册"处理
return LoginResult{}, ErrUserAlreadyExists