fix: 订阅模式登录验证、永久会员类型区分、动态代码HTTP返回值修复、侧边栏滚动位置保持
- 修复订阅模式登录时错误检查余额的问题 - 区分无限余额和永久订阅两种永久会员类型 - 修复动态代码HTTP请求返回值在JS中无法正确访问的问题 - 添加侧边栏滚动位置保持功能 - 移除developer角色相关代码,统一使用admin - 添加缺失的i18n翻译key
This commit is contained in:
@@ -116,13 +116,24 @@ func handleAppHeartbeat(c *gin.Context) {
|
||||
}
|
||||
|
||||
if shouldDeduct {
|
||||
if user.Balance >= app.DeductionAmount {
|
||||
user.Balance -= app.DeductionAmount
|
||||
log.Printf("[DEBUG] Deducted %.2f from user %d, new balance: %.2f", app.DeductionAmount, user.ID, user.Balance)
|
||||
if user.Balance == -1 {
|
||||
log.Printf("[DEBUG] User %d is permanent member, skip deduction", user.ID)
|
||||
} else if app.BillingType == "subscription" {
|
||||
if user.ExpiryAt == nil || user.ExpiryAt.Before(now) {
|
||||
log.Printf("[DEBUG] User %d subscription expired, ExpiryAt=%v", user.ID, user.ExpiryAt)
|
||||
response.Error(c, 403, "订阅已过期")
|
||||
return
|
||||
}
|
||||
log.Printf("[DEBUG] User %d subscription valid, skip balance deduction", user.ID)
|
||||
} else {
|
||||
log.Printf("[DEBUG] User %d has insufficient balance: %.2f < %.2f", user.ID, user.Balance, app.DeductionAmount)
|
||||
response.Error(c, 403, "余额不足")
|
||||
return
|
||||
if user.Balance >= app.DeductionAmount {
|
||||
user.Balance -= app.DeductionAmount
|
||||
log.Printf("[DEBUG] Deducted %.2f from user %d, new balance: %.2f", app.DeductionAmount, user.ID, user.Balance)
|
||||
} else {
|
||||
log.Printf("[DEBUG] User %d has insufficient balance: %.2f < %.2f", user.ID, user.Balance, app.DeductionAmount)
|
||||
response.Error(c, 403, "余额不足")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,11 +456,24 @@ func handleAppLogin(c *gin.Context) {
|
||||
log.Printf("[DEBUG] isTrialValid=%v, IsTrialUser=%v, TrialEndAt=%v, Balance=%f", isTrialValid, user.IsTrialUser, user.TrialEndAt, user.Balance)
|
||||
|
||||
if !isTrialValid {
|
||||
if appModel.BillingType != "free" && user.Balance <= 0 {
|
||||
log.Printf("[DEBUG] User %d has no balance remaining", user.ID)
|
||||
service.LogVerification(c, &appModel.ID, &user.ID, "login_failed", "登录失败: 余额不足 - "+req.Username, req.DeviceID, fmt.Errorf("余额不足,请充值后继续使用"))
|
||||
response.Error(c, 403, "余额不足,请充值后继续使用")
|
||||
return
|
||||
if appModel.BillingType != "free" {
|
||||
if user.Balance == -1 {
|
||||
log.Printf("[DEBUG] User %d is permanent member, allowing login", user.ID)
|
||||
} else if appModel.BillingType == "subscription" {
|
||||
if user.ExpiryAt == nil || user.ExpiryAt.Before(time.Now()) {
|
||||
log.Printf("[DEBUG] User %d subscription expired, ExpiryAt=%v", user.ID, user.ExpiryAt)
|
||||
service.LogVerification(c, &appModel.ID, &user.ID, "login_failed", "登录失败: 订阅已过期 - "+req.Username, req.DeviceID, fmt.Errorf("订阅已过期,请充值后继续使用"))
|
||||
response.Error(c, 403, "订阅已过期,请充值后继续使用")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if user.Balance <= 0 {
|
||||
log.Printf("[DEBUG] User %d has no balance remaining", user.ID)
|
||||
service.LogVerification(c, &appModel.ID, &user.ID, "login_failed", "登录失败: 余额不足 - "+req.Username, req.DeviceID, fmt.Errorf("余额不足,请充值后继续使用"))
|
||||
response.Error(c, 403, "余额不足,请充值后继续使用")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -549,18 +549,18 @@ func handleAppUploadVariableBinary(c *gin.Context) {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var developer model.User
|
||||
if err := database.DB.First(&developer, app.UserID).Error; err != nil {
|
||||
response.Error(c, 500, "获取开发者信息失败")
|
||||
var adminUser model.User
|
||||
if err := database.DB.First(&adminUser, app.UserID).Error; err != nil {
|
||||
response.Error(c, 500, "获取管理员信息失败")
|
||||
return
|
||||
}
|
||||
|
||||
if developer.CurrentPackageID != nil {
|
||||
if adminUser.CurrentPackageID != nil {
|
||||
var permission model.PackagePermission
|
||||
if err := database.DB.Where("package_id = ?", developer.CurrentPackageID).First(&permission).Error; err == nil {
|
||||
if err := database.DB.Where("package_id = ?", adminUser.CurrentPackageID).First(&permission).Error; err == nil {
|
||||
maxStorageBytes := int64(permission.MaxStorage) * 1024 * 1024
|
||||
if developer.StorageUsed+header.Size > maxStorageBytes {
|
||||
usedMB := float64(developer.StorageUsed) / 1024 / 1024
|
||||
if adminUser.StorageUsed+header.Size > maxStorageBytes {
|
||||
usedMB := float64(adminUser.StorageUsed) / 1024 / 1024
|
||||
maxMB := float64(permission.MaxStorage)
|
||||
response.Error(c, 403, fmt.Sprintf("存储空间不足,已使用 %.2f MB / %.2f MB", usedMB, maxMB))
|
||||
return
|
||||
|
||||
@@ -250,19 +250,35 @@ func handleExecuteDynamicCode(c *gin.Context) {
|
||||
|
||||
httpClient := httputil.NewHTTPClient(10 * time.Second)
|
||||
httpObj := map[string]interface{}{
|
||||
"get": func(url string, headers map[string]interface{}) *httputil.HTTPResponse {
|
||||
"get": func(url string, headers map[string]interface{}) map[string]interface{} {
|
||||
convertedHeaders := make(map[string]string)
|
||||
for k, v := range headers {
|
||||
convertedHeaders[k] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
return httpClient.Get(url, convertedHeaders)
|
||||
resp := httpClient.Get(url, convertedHeaders)
|
||||
return map[string]interface{}{
|
||||
"statusCode": resp.StatusCode,
|
||||
"status": resp.Status,
|
||||
"headers": resp.Headers,
|
||||
"body": resp.Body,
|
||||
"json": resp.JSON,
|
||||
"error": resp.Error,
|
||||
}
|
||||
},
|
||||
"post": func(url string, headers map[string]interface{}, body interface{}) *httputil.HTTPResponse {
|
||||
"post": func(url string, headers map[string]interface{}, body interface{}) map[string]interface{} {
|
||||
convertedHeaders := make(map[string]string)
|
||||
for k, v := range headers {
|
||||
convertedHeaders[k] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
return httpClient.Post(url, convertedHeaders, body)
|
||||
resp := httpClient.Post(url, convertedHeaders, body)
|
||||
return map[string]interface{}{
|
||||
"statusCode": resp.StatusCode,
|
||||
"status": resp.Status,
|
||||
"headers": resp.Headers,
|
||||
"body": resp.Body,
|
||||
"json": resp.JSON,
|
||||
"error": resp.Error,
|
||||
}
|
||||
},
|
||||
}
|
||||
if err := vm.Set("http", httpObj); err != nil {
|
||||
|
||||
@@ -91,8 +91,14 @@ func handleAppRecharge(c *gin.Context) {
|
||||
user.IsTrialUser = false
|
||||
|
||||
if card.CardType.Value == -1 {
|
||||
user.Balance = -1
|
||||
user.ExpiryAt = nil
|
||||
if card.CardType.RechargeType == "subscription" {
|
||||
permanentExpiry := time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
|
||||
user.ExpiryAt = &permanentExpiry
|
||||
user.Balance = -1
|
||||
} else {
|
||||
user.Balance = -1
|
||||
user.ExpiryAt = nil
|
||||
}
|
||||
} else {
|
||||
switch card.CardType.RechargeType {
|
||||
case "subscription":
|
||||
|
||||
Reference in New Issue
Block a user