修复节点无法编辑的错误
Some checks failed
build / build (api, amd64, linux) (push) Failing after -50s
build / build (api, arm64, linux) (push) Failing after -52s
build / build (api.exe, amd64, windows) (push) Failing after -51s

This commit is contained in:
CN-JS-HuiBai
2026-04-18 10:31:31 +08:00
parent 6e75b7d7d5
commit 98379b21f4
6 changed files with 275 additions and 130 deletions

View File

@@ -18,6 +18,8 @@ func ipv6StatusPresentation(status string, allowed bool) (string, string, string
switch status {
case "active":
return "active", "IPv6 enabled", ""
case "disabled":
return "disabled", "IPv6 disabled", ""
case "eligible":
return "eligible", "Ready to enable", ""
case "", "not_allowed", "not_eligible", "disallowed":
@@ -233,7 +235,7 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
planNameValue := planNames[shadowPlanID]
if hasShadowUser {
planID = intFromPointer(shadowUser.PlanID)
planNameValue = planName(shadowUser.Plan)
planNameValue = firstString(planName(shadowUser.Plan), planNames[planID])
}
shadowUserID := 0
shadowUpdatedAt := int64(0)
@@ -346,6 +348,11 @@ func AdminIPv6SubscriptionEnable(c *gin.Context) {
return
}
var payload struct {
PlanID int `json:"plan_id"`
}
_ = c.ShouldBindJSON(&payload)
var user model.User
if err := database.DB.Preload("Plan").First(&user, userID).Error; err != nil {
Fail(c, 404, "user not found")
@@ -356,14 +363,35 @@ func AdminIPv6SubscriptionEnable(c *gin.Context) {
return
}
if !service.SyncIPv6ShadowAccount(&user) {
Fail(c, 403, "user plan does not support ipv6 subscription")
if !service.SyncIPv6ShadowAccountWithPlan(&user, payload.PlanID) {
Fail(c, 500, "failed to create/sync IPv6 subscription")
return
}
SuccessMessage(c, "IPv6 subscription enabled/synced", true)
}
func AdminIPv6SubscriptionDisable(c *gin.Context) {
userID := parsePositiveInt(c.Param("userId"), 0)
if userID == 0 {
Fail(c, 400, "invalid user id")
return
}
var user model.User
if err := database.DB.First(&user, userID).Error; err != nil {
Fail(c, 404, "user not found")
return
}
if !service.DisableIPv6ShadowAccount(&user) {
Fail(c, 500, "failed to disable IPv6 subscription")
return
}
SuccessMessage(c, "IPv6 subscription disabled", true)
}
func AdminIPv6SubscriptionSyncPassword(c *gin.Context) {
userID := parsePositiveInt(c.Param("userId"), 0)
if userID == 0 {

View File

@@ -74,19 +74,14 @@ func GetPluginConfigBool(code, key string, defaultValue bool) bool {
}
func SyncIPv6ShadowAccount(user *model.User) bool {
if user == nil {
return false
}
return SyncIPv6ShadowAccountWithPlan(user, 0)
}
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
}
}
if !PluginUserAllowed(user, plan) {
syncIPv6SubscriptionRecord(user, nil, false, "not_allowed")
// SyncIPv6ShadowAccountWithPlan creates or syncs an IPv6 shadow account.
// If overridePlanID > 0, it overrides the global ipv6_plan_id config for this user.
// This function no longer checks PluginUserAllowed — it is admin-only.
func SyncIPv6ShadowAccountWithPlan(user *model.User, overridePlanID int) bool {
if user == nil {
return false
}
@@ -113,9 +108,13 @@ func SyncIPv6ShadowAccount(user *model.User) bool {
ipv6User.U = 0
ipv6User.D = 0
ipv6User.T = 0
ipv6User.Banned = false
ipv6User.UpdatedAt = now
if planID := parsePluginPositiveInt(GetPluginConfigString(PluginUserAddIPv6, "ipv6_plan_id", "0"), 0); planID > 0 {
// Determine which plan to assign: override > global config
if overridePlanID > 0 {
ipv6User.PlanID = &overridePlanID
} else if planID := parsePluginPositiveInt(GetPluginConfigString(PluginUserAddIPv6, "ipv6_plan_id", "0"), 0); planID > 0 {
ipv6User.PlanID = &planID
}
if groupID := parsePluginPositiveInt(GetPluginConfigString(PluginUserAddIPv6, "ipv6_group_id", "0"), 0); groupID > 0 {
@@ -134,6 +133,32 @@ func SyncIPv6ShadowAccount(user *model.User) bool {
return true
}
// DisableIPv6ShadowAccount soft-disables the IPv6 shadow account for a user.
// It bans the shadow user and marks the subscription as disabled.
func DisableIPv6ShadowAccount(user *model.User) bool {
if user == nil {
return false
}
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 {
// No shadow user found, just update subscription record
syncIPv6SubscriptionRecord(user, nil, false, "disabled")
return true
}
// Ban the shadow user (soft disable)
now := time.Now().Unix()
_ = database.DB.Model(&model.User{}).Where("id = ?", ipv6User.ID).Updates(map[string]any{
"banned": true,
"updated_at": now,
}).Error
syncIPv6SubscriptionRecord(user, &ipv6User, false, "disabled")
return true
}
func PluginPlanAllowed(plan *model.Plan) bool {
return PluginUserAllowed(nil, plan)
}