修复IPv6插件的逻辑错误
Some checks failed
build / build (api, amd64, linux) (push) Failing after -50s
build / build (api, arm64, linux) (push) Failing after -51s
build / build (api.exe, amd64, windows) (push) Failing after -51s

This commit is contained in:
CN-JS-HuiBai
2026-04-18 11:18:36 +08:00
parent 98379b21f4
commit def8352bbb
4 changed files with 218 additions and 147 deletions

View File

@@ -183,29 +183,39 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
}
subscriptionByUserID := make(map[int]model.UserIPv6Subscription, len(userIDs))
shadowUserIDs := make([]int, 0, len(userIDs))
if len(userIDs) > 0 {
var rows []model.UserIPv6Subscription
if err := database.DB.Where("user_id IN ?", userIDs).Find(&rows).Error; err == nil {
for _, row := range rows {
subscriptionByUserID[row.UserID] = row
if row.ShadowUserID != nil && *row.ShadowUserID > 0 {
shadowUserIDs = append(shadowUserIDs, *row.ShadowUserID)
}
}
}
}
shadowByParentID := make(map[int]model.User, len(userIDs))
shadowByID := make(map[int]model.User, len(shadowUserIDs))
shadowByEmail := make(map[string]model.User, len(userIDs))
if len(userIDs) > 0 {
var shadowUsers []model.User
if err := database.DB.Preload("Plan").Where("parent_id IN ?", userIDs).Find(&shadowUsers).Error; err == nil {
query := database.DB.Preload("Plan")
if len(shadowUserIDs) > 0 {
query = query.Where("parent_id IN ? OR id IN ?", userIDs, shadowUserIDs)
} else {
query = query.Where("parent_id IN ?", userIDs)
}
if err := query.Find(&shadowUsers).Error; err == nil {
for _, shadow := range shadowUsers {
shadowByID[shadow.ID] = shadow
shadowByEmail[strings.ToLower(shadow.Email)] = shadow
if shadow.ParentID != nil {
shadowByParentID[*shadow.ParentID] = shadow
}
}
}
}
shadowPlanID := parsePositiveInt(
service.GetPluginConfigString(service.PluginUserAddIPv6, "ipv6_plan_id", "0"),
0,
)
planNames := make(map[int]string)
var plans []model.Plan
if err := database.DB.Select("id", "name").Find(&plans).Error; err == nil {
@@ -218,6 +228,12 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
for _, user := range users {
subscription, hasSubscription := subscriptionByUserID[user.ID]
shadowUser, hasShadowUser := shadowByParentID[user.ID]
if !hasShadowUser && hasSubscription && subscription.ShadowUserID != nil {
shadowUser, hasShadowUser = shadowByID[*subscription.ShadowUserID]
}
if !hasShadowUser {
shadowUser, hasShadowUser = shadowByEmail[strings.ToLower(service.IPv6ShadowEmail(user.Email))]
}
if !hasSubscription && hasShadowUser {
subscription = model.UserIPv6Subscription{
UserID: user.ID,
@@ -229,10 +245,9 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
}
hasSubscription = true
}
allowed := service.PluginUserAllowed(&user, user.Plan)
status := "not_allowed"
planID := shadowPlanID
planNameValue := planNames[shadowPlanID]
status := "eligible"
planID := 0
planNameValue := ""
if hasShadowUser {
planID = intFromPointer(shadowUser.PlanID)
planNameValue = firstString(planName(shadowUser.Plan), planNames[planID])
@@ -246,14 +261,14 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
}
shadowUpdatedAt = subscription.UpdatedAt
}
effectiveAllowed := allowed || hasSubscription && subscription.Allowed
effectiveAllowed := true
status, statusLabel, _ := ipv6StatusPresentation(status, effectiveAllowed)
list = append(list, gin.H{
"id": user.ID,
"email": user.Email,
"plan_id": planID,
"plan_name": firstString(planNameValue, "-"),
"plan_name": planNameValue,
"allowed": effectiveAllowed,
"is_active": hasSubscription && subscription.Status == "active",
"status": status,
@@ -463,22 +478,13 @@ func PluginUserAddIPv6Check(c *gin.Context) {
return
}
var plan *model.Plan
if user.PlanID != nil {
var loadedPlan model.Plan
if err := database.DB.First(&loadedPlan, *user.PlanID).Error; err == nil {
plan = &loadedPlan
}
}
var subscription model.UserIPv6Subscription
hasSubscription := database.DB.Where("user_id = ?", user.ID).First(&subscription).Error == nil
allowed := service.PluginUserAllowed(user, plan)
status := "not_allowed"
status := "eligible"
if hasSubscription {
status = firstString(subscription.Status, "active")
}
effectiveAllowed := allowed || hasSubscription && subscription.Allowed
effectiveAllowed := true
status, statusLabel, reason := ipv6StatusPresentation(status, effectiveAllowed)
Success(c, gin.H{

View File

@@ -105,6 +105,7 @@ func SyncIPv6ShadowAccountWithPlan(user *model.User, overridePlanID int) bool {
ipv6User.Email = ipv6Email
ipv6User.Password = user.Password
ipv6User.ParentID = &user.ID
ipv6User.U = 0
ipv6User.D = 0
ipv6User.T = 0
@@ -116,6 +117,8 @@ func SyncIPv6ShadowAccountWithPlan(user *model.User, overridePlanID int) bool {
ipv6User.PlanID = &overridePlanID
} else if planID := parsePluginPositiveInt(GetPluginConfigString(PluginUserAddIPv6, "ipv6_plan_id", "0"), 0); planID > 0 {
ipv6User.PlanID = &planID
} else if ipv6User.PlanID == nil && user.PlanID != nil {
ipv6User.PlanID = user.PlanID
}
if groupID := parsePluginPositiveInt(GetPluginConfigString(PluginUserAddIPv6, "ipv6_group_id", "0"), 0); groupID > 0 {
ipv6User.GroupID = &groupID
@@ -142,7 +145,15 @@ func DisableIPv6ShadowAccount(user *model.User) bool {
ipv6Email := IPv6ShadowEmail(user.Email)
var ipv6User model.User
if err := database.DB.Where("email = ? AND parent_id = ?", ipv6Email, user.ID).First(&ipv6User).Error; err != nil {
var subscription model.UserIPv6Subscription
if err := database.DB.Where("user_id = ?", user.ID).First(&subscription).Error; err == nil && subscription.ShadowUserID != nil {
_ = database.DB.First(&ipv6User, *subscription.ShadowUserID).Error
}
if ipv6User.ID == 0 {
_ = database.DB.Where("email = ?", ipv6Email).First(&ipv6User).Error
}
if ipv6User.ID == 0 {
// No shadow user found, just update subscription record
syncIPv6SubscriptionRecord(user, nil, false, "disabled")
return true