Merge branch 'main' into feature/distribution-system
合入 main 的推广追踪(adtracking)模块,并解决与分销业务的 8 处冲突。 冲突解决原则:两边的字段、菜单与路由全部保留,不删任何一方。 后端: - model/order.go:保留分销字段注释块,追加 SourceTrackCode - model/user.go:追加 RegisterTrackCode;TokenVersion 默认值保持 1 (与本库 users.token_version 列默认值一致) - auth/repository.go:两处建号结构体同时写入 RegisterTrackCode 与 TokenVersion - order/dto.go:OrderDTO 同时暴露 distribution_site_id 与 source_track_code; CreateRequest 同时接受 distribution_site_code 与 track_code - order/presenter.go:同时映射 DistributionSiteID 与 SourceTrackCode 前端: - orders/api/orders.ts:createOrder 同时携带 distribution_site_code 与 track_code - layouts/AdminLayout.vue:分销管理菜单组与推广追踪菜单组并列保留 - router/adminRoutes.ts:分销 4 条路由与 tracking-links 路由并列保留 迁移:feature 侧 000064-000067 已在前一提交顺延为 000065-000068, 为 main 的 000064_ad_tracking 让号,合并后编号 000063→000068 连续无重复。
This commit is contained in:
@@ -3,6 +3,8 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"hfb_sys/backend/internal/model"
|
||||
@@ -11,6 +13,16 @@ import (
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
var trackCodePattern = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,64}$`)
|
||||
|
||||
func sanitizeTrackCode(code string) string {
|
||||
s := strings.TrimSpace(code)
|
||||
if len(s) == 0 || len(s) > 64 || !trackCodePattern.MatchString(s) {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type UserRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
@@ -57,17 +69,22 @@ func (r *UserRepository) UpdateProfile(ctx context.Context, id uint64, nickname
|
||||
return r.FindByID(ctx, id)
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindOrCreateByPhone(ctx context.Context, phone string) (*model.User, error) {
|
||||
func (r *UserRepository) FindOrCreateByPhone(ctx context.Context, phone string, trackCode ...string) (*model.User, error) {
|
||||
now := time.Now()
|
||||
var code string
|
||||
if len(trackCode) > 0 {
|
||||
code = sanitizeTrackCode(trackCode[0])
|
||||
}
|
||||
user := model.User{
|
||||
Phone: phone,
|
||||
Nickname: "用户" + phone[len(phone)-4:],
|
||||
RealnameStatus: "unverified",
|
||||
RiskStatus: "normal",
|
||||
CreditScore: 100,
|
||||
Status: "active",
|
||||
TokenVersion: 1,
|
||||
LastLoginAt: &now,
|
||||
Phone: phone,
|
||||
Nickname: "用户" + phone[len(phone)-4:],
|
||||
RealnameStatus: "unverified",
|
||||
RiskStatus: "normal",
|
||||
CreditScore: 100,
|
||||
Status: "active",
|
||||
RegisterTrackCode: code,
|
||||
TokenVersion: 1,
|
||||
LastLoginAt: &now,
|
||||
}
|
||||
|
||||
err := r.db.WithContext(ctx).Clauses(clause.OnConflict{
|
||||
@@ -106,18 +123,23 @@ func (r *UserRepository) RevokeTokens(ctx context.Context, userID uint64) error
|
||||
UpdateColumn("token_version", gorm.Expr("token_version + 1")).Error
|
||||
}
|
||||
|
||||
func (r *UserRepository) RegisterWithPassword(ctx context.Context, phone string, hash string) (*model.User, error) {
|
||||
func (r *UserRepository) RegisterWithPassword(ctx context.Context, phone string, hash string, trackCode ...string) (*model.User, error) {
|
||||
now := time.Now()
|
||||
var code string
|
||||
if len(trackCode) > 0 {
|
||||
code = sanitizeTrackCode(trackCode[0])
|
||||
}
|
||||
user := model.User{
|
||||
Phone: phone,
|
||||
PasswordHash: hash,
|
||||
Nickname: "用户" + phone[len(phone)-4:],
|
||||
RealnameStatus: "unverified",
|
||||
RiskStatus: "normal",
|
||||
CreditScore: 100,
|
||||
Status: "active",
|
||||
TokenVersion: 1,
|
||||
LastLoginAt: &now,
|
||||
Phone: phone,
|
||||
PasswordHash: hash,
|
||||
Nickname: "用户" + phone[len(phone)-4:],
|
||||
RealnameStatus: "unverified",
|
||||
RiskStatus: "normal",
|
||||
CreditScore: 100,
|
||||
Status: "active",
|
||||
RegisterTrackCode: code,
|
||||
TokenVersion: 1,
|
||||
LastLoginAt: &now,
|
||||
}
|
||||
|
||||
err := r.db.WithContext(ctx).Create(&user).Error
|
||||
|
||||
Reference in New Issue
Block a user