release: prepare v0.1.132
This commit is contained in:
@@ -175,6 +175,11 @@ func (s *stubAdminService) UpdateUserBalance(ctx context.Context, userID int64,
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (s *stubAdminService) RefreshUserRegistrationIPLocation(ctx context.Context, userID int64) (*service.User, error) {
|
||||
user := service.User{ID: userID, Email: "user@example.com", Status: service.StatusActive, RegisterIPAddress: "8.8.8.8", RegisterIPLocation: "美国"}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (s *stubAdminService) BatchUpdateConcurrency(ctx context.Context, userIDs []int64, value int, mode string) (int, error) {
|
||||
return len(userIDs), nil
|
||||
}
|
||||
|
||||
@@ -204,6 +204,7 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
|
||||
AffiliateRebateFreezeHours: settings.AffiliateRebateFreezeHours,
|
||||
AffiliateRebateDurationDays: settings.AffiliateRebateDurationDays,
|
||||
AffiliateRebatePerInviteeCap: settings.AffiliateRebatePerInviteeCap,
|
||||
AffiliateInviteBalanceReward: settings.AffiliateInviteBalanceReward,
|
||||
DefaultUserRPMLimit: settings.DefaultUserRPMLimit,
|
||||
DefaultSubscriptions: defaultSubscriptions,
|
||||
EnableModelFallback: settings.EnableModelFallback,
|
||||
@@ -452,6 +453,7 @@ type UpdateSettingsRequest struct {
|
||||
AffiliateRebateFreezeHours *int `json:"affiliate_rebate_freeze_hours"`
|
||||
AffiliateRebateDurationDays *int `json:"affiliate_rebate_duration_days"`
|
||||
AffiliateRebatePerInviteeCap *float64 `json:"affiliate_rebate_per_invitee_cap"`
|
||||
AffiliateInviteBalanceReward *float64 `json:"affiliate_invite_balance_reward"`
|
||||
DefaultUserRPMLimit int `json:"default_user_rpm_limit"`
|
||||
DefaultSubscriptions []dto.DefaultSubscriptionSetting `json:"default_subscriptions"`
|
||||
AuthSourceDefaultEmailBalance *float64 `json:"auth_source_default_email_balance"`
|
||||
@@ -641,6 +643,13 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
||||
if affiliateRebatePerInviteeCap < 0 {
|
||||
affiliateRebatePerInviteeCap = service.AffiliateRebatePerInviteeCapDefault
|
||||
}
|
||||
affiliateInviteBalanceReward := previousSettings.AffiliateInviteBalanceReward
|
||||
if req.AffiliateInviteBalanceReward != nil {
|
||||
affiliateInviteBalanceReward = *req.AffiliateInviteBalanceReward
|
||||
}
|
||||
if affiliateInviteBalanceReward < 0 {
|
||||
affiliateInviteBalanceReward = service.AffiliateInviteBalanceRewardDefault
|
||||
}
|
||||
// 通用表格配置:兼容旧客户端未传字段时保留当前值。
|
||||
if req.TableDefaultPageSize <= 0 {
|
||||
req.TableDefaultPageSize = previousSettings.TableDefaultPageSize
|
||||
@@ -1374,6 +1383,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
||||
AffiliateRebateFreezeHours: affiliateRebateFreezeHours,
|
||||
AffiliateRebateDurationDays: affiliateRebateDurationDays,
|
||||
AffiliateRebatePerInviteeCap: affiliateRebatePerInviteeCap,
|
||||
AffiliateInviteBalanceReward: affiliateInviteBalanceReward,
|
||||
DefaultUserRPMLimit: req.DefaultUserRPMLimit,
|
||||
DefaultSubscriptions: defaultSubscriptions,
|
||||
EnableModelFallback: req.EnableModelFallback,
|
||||
@@ -1758,6 +1768,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
||||
AffiliateRebateFreezeHours: updatedSettings.AffiliateRebateFreezeHours,
|
||||
AffiliateRebateDurationDays: updatedSettings.AffiliateRebateDurationDays,
|
||||
AffiliateRebatePerInviteeCap: updatedSettings.AffiliateRebatePerInviteeCap,
|
||||
AffiliateInviteBalanceReward: updatedSettings.AffiliateInviteBalanceReward,
|
||||
DefaultUserRPMLimit: updatedSettings.DefaultUserRPMLimit,
|
||||
DefaultSubscriptions: updatedDefaultSubscriptions,
|
||||
EnableModelFallback: updatedSettings.EnableModelFallback,
|
||||
@@ -2099,6 +2110,9 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings,
|
||||
if before.AffiliateRebatePerInviteeCap != after.AffiliateRebatePerInviteeCap {
|
||||
changed = append(changed, "affiliate_rebate_per_invitee_cap")
|
||||
}
|
||||
if before.AffiliateInviteBalanceReward != after.AffiliateInviteBalanceReward {
|
||||
changed = append(changed, "affiliate_invite_balance_reward")
|
||||
}
|
||||
if !equalDefaultSubscriptions(before.DefaultSubscriptions, after.DefaultSubscriptions) {
|
||||
changed = append(changed, "default_subscriptions")
|
||||
}
|
||||
|
||||
@@ -341,6 +341,24 @@ func (h *UserHandler) UpdateBalance(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// RefreshRegistrationIPLocation handles refreshing signup IP location.
|
||||
// POST /api/v1/admin/users/:id/register-ip-location
|
||||
func (h *UserHandler) RefreshRegistrationIPLocation(c *gin.Context) {
|
||||
userID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
response.BadRequest(c, "Invalid user ID")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.adminService.RefreshUserRegistrationIPLocation(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, dto.UserFromServiceAdmin(user))
|
||||
}
|
||||
|
||||
// GetUserAPIKeys handles getting user's API keys
|
||||
// GET /api/v1/admin/users/:id/api-keys
|
||||
func (h *UserHandler) GetUserAPIKeys(c *gin.Context) {
|
||||
|
||||
@@ -362,7 +362,7 @@ func (h *AuthHandler) completeEmailOAuthRegistration(c *gin.Context, provider st
|
||||
}
|
||||
|
||||
tokenPair, user, err := h.authService.RegisterVerifiedOAuthEmailAccount(
|
||||
c.Request.Context(),
|
||||
registrationIPContext(c),
|
||||
strings.TrimSpace(session.ResolvedEmail),
|
||||
req.Password,
|
||||
strings.TrimSpace(req.InvitationCode),
|
||||
|
||||
@@ -352,6 +352,10 @@ func (r *oauthEmailAffiliateRepoStub) AccrueQuota(context.Context, int64, int64,
|
||||
panic("unexpected AccrueQuota call")
|
||||
}
|
||||
|
||||
func (r *oauthEmailAffiliateRepoStub) CreditInviteBalanceReward(context.Context, int64, int64, float64) (float64, error) {
|
||||
panic("unexpected CreditInviteBalanceReward call")
|
||||
}
|
||||
|
||||
func (r *oauthEmailAffiliateRepoStub) GetAccruedRebateFromInvitee(context.Context, int64, int64) (float64, error) {
|
||||
panic("unexpected GetAccruedRebateFromInvitee call")
|
||||
}
|
||||
|
||||
@@ -150,6 +150,15 @@ func (h *AuthHandler) isBackendModeEnabled(ctx context.Context) bool {
|
||||
return h.settingSvc.IsBackendModeEnabled(ctx)
|
||||
}
|
||||
|
||||
func registrationIPContext(c *gin.Context) context.Context {
|
||||
base := c.Request.Context()
|
||||
clientIP := strings.TrimSpace(ip.GetClientIP(c))
|
||||
if clientIP == "" {
|
||||
return base
|
||||
}
|
||||
return service.WithRegistrationIPInfo(base, service.RegistrationIPInfo{IPAddress: clientIP})
|
||||
}
|
||||
|
||||
// Register handles user registration
|
||||
// POST /api/v1/auth/register
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
@@ -166,7 +175,7 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
||||
}
|
||||
|
||||
_, user, err := h.authService.RegisterWithVerification(
|
||||
c.Request.Context(),
|
||||
registrationIPContext(c),
|
||||
req.Email,
|
||||
req.Password,
|
||||
req.VerifyCode,
|
||||
|
||||
@@ -519,7 +519,7 @@ func (h *AuthHandler) CompleteLinuxDoOAuthRegistration(c *gin.Context) {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
tokenPair, user, err := h.authService.LoginOrRegisterOAuthWithTokenPair(c.Request.Context(), email, username, req.InvitationCode, req.AffCode)
|
||||
tokenPair, user, err := h.authService.LoginOrRegisterOAuthWithTokenPair(registrationIPContext(c), email, username, req.InvitationCode, req.AffCode)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
|
||||
@@ -1673,7 +1673,7 @@ func (h *AuthHandler) createPendingOAuthAccount(c *gin.Context, provider string)
|
||||
}
|
||||
|
||||
tokenPair, user, err := h.authService.RegisterOAuthEmailAccount(
|
||||
c.Request.Context(),
|
||||
registrationIPContext(c),
|
||||
email,
|
||||
req.Password,
|
||||
strings.TrimSpace(req.VerifyCode),
|
||||
|
||||
@@ -666,7 +666,7 @@ func (h *AuthHandler) CompleteOIDCOAuthRegistration(c *gin.Context) {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
tokenPair, user, err := h.authService.LoginOrRegisterOAuthWithTokenPair(c.Request.Context(), email, username, req.InvitationCode, req.AffCode)
|
||||
tokenPair, user, err := h.authService.LoginOrRegisterOAuthWithTokenPair(registrationIPContext(c), email, username, req.InvitationCode, req.AffCode)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
|
||||
@@ -548,7 +548,7 @@ func (h *AuthHandler) CompleteWeChatOAuthRegistration(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
tokenPair, user, err := h.authService.LoginOrRegisterOAuthWithTokenPair(c.Request.Context(), email, username, req.InvitationCode, req.AffCode)
|
||||
tokenPair, user, err := h.authService.LoginOrRegisterOAuthWithTokenPair(registrationIPContext(c), email, username, req.InvitationCode, req.AffCode)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
|
||||
@@ -21,6 +21,12 @@ func UserFromServiceShallow(u *service.User) *User {
|
||||
Concurrency: u.Concurrency,
|
||||
Status: u.Status,
|
||||
AllowedGroups: u.AllowedGroups,
|
||||
RegisterIPAddress: u.RegisterIPAddress,
|
||||
RegisterIPCountry: u.RegisterIPCountry,
|
||||
RegisterIPCountryCode: u.RegisterIPCountryCode,
|
||||
RegisterIPRegion: u.RegisterIPRegion,
|
||||
RegisterIPCity: u.RegisterIPCity,
|
||||
RegisterIPLocation: u.RegisterIPLocation,
|
||||
LastActiveAt: u.LastActiveAt,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
|
||||
@@ -129,6 +129,7 @@ type SystemSettings struct {
|
||||
AffiliateRebateFreezeHours int `json:"affiliate_rebate_freeze_hours"`
|
||||
AffiliateRebateDurationDays int `json:"affiliate_rebate_duration_days"`
|
||||
AffiliateRebatePerInviteeCap float64 `json:"affiliate_rebate_per_invitee_cap"`
|
||||
AffiliateInviteBalanceReward float64 `json:"affiliate_invite_balance_reward"`
|
||||
DefaultUserRPMLimit int `json:"default_user_rpm_limit"`
|
||||
DefaultSubscriptions []DefaultSubscriptionSetting `json:"default_subscriptions"`
|
||||
|
||||
|
||||
@@ -7,17 +7,23 @@ import (
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
Role string `json:"role"`
|
||||
Balance float64 `json:"balance"`
|
||||
Concurrency int `json:"concurrency"`
|
||||
Status string `json:"status"`
|
||||
AllowedGroups []int64 `json:"allowed_groups"`
|
||||
LastActiveAt *time.Time `json:"last_active_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID int64 `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
Role string `json:"role"`
|
||||
Balance float64 `json:"balance"`
|
||||
Concurrency int `json:"concurrency"`
|
||||
Status string `json:"status"`
|
||||
AllowedGroups []int64 `json:"allowed_groups"`
|
||||
RegisterIPAddress string `json:"register_ip_address,omitempty"`
|
||||
RegisterIPCountry string `json:"register_ip_country,omitempty"`
|
||||
RegisterIPCountryCode string `json:"register_ip_country_code,omitempty"`
|
||||
RegisterIPRegion string `json:"register_ip_region,omitempty"`
|
||||
RegisterIPCity string `json:"register_ip_city,omitempty"`
|
||||
RegisterIPLocation string `json:"register_ip_location,omitempty"`
|
||||
LastActiveAt *time.Time `json:"last_active_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 余额不足通知
|
||||
BalanceNotifyEnabled bool `json:"balance_notify_enabled"`
|
||||
|
||||
Reference in New Issue
Block a user