软件功能基本开发完成,内测BUG等待修复
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"xboard-go/internal/database"
|
||||
@@ -11,6 +13,31 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ipv6StatusPresentation(status string, allowed bool) (string, string, string) {
|
||||
status = strings.TrimSpace(strings.ToLower(status))
|
||||
switch status {
|
||||
case "active":
|
||||
return "active", "IPv6 enabled", ""
|
||||
case "eligible":
|
||||
return "eligible", "Ready to enable", ""
|
||||
case "", "not_allowed", "not_eligible", "disallowed":
|
||||
if allowed {
|
||||
return "eligible", "Ready to enable", ""
|
||||
}
|
||||
return "not_allowed", "Not eligible", "Current plan or group is not allowed to enable IPv6"
|
||||
default:
|
||||
label := strings.ReplaceAll(strings.Title(strings.ReplaceAll(status, "_", " ")), "Ipv6", "IPv6")
|
||||
if strings.EqualFold(label, "Not Allowed") {
|
||||
label = "Not eligible"
|
||||
}
|
||||
reason := ""
|
||||
if !allowed && (status == "not_allowed" || status == "not_eligible") {
|
||||
reason = "Current plan or group is not allowed to enable IPv6"
|
||||
}
|
||||
return status, label, reason
|
||||
}
|
||||
}
|
||||
|
||||
func PluginUserOnlineDevicesUsers(c *gin.Context) {
|
||||
|
||||
page := parsePositiveInt(c.DefaultQuery("page", "1"), 1)
|
||||
@@ -165,7 +192,7 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
|
||||
shadowByParentID := make(map[int]model.User, len(userIDs))
|
||||
if len(userIDs) > 0 {
|
||||
var shadowUsers []model.User
|
||||
if err := database.DB.Where("parent_id IN ?", userIDs).Find(&shadowUsers).Error; err == nil {
|
||||
if err := database.DB.Preload("Plan").Where("parent_id IN ?", userIDs).Find(&shadowUsers).Error; err == nil {
|
||||
for _, shadow := range shadowUsers {
|
||||
if shadow.ParentID != nil {
|
||||
shadowByParentID[*shadow.ParentID] = shadow
|
||||
@@ -173,6 +200,17 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
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 {
|
||||
for _, plan := range plans {
|
||||
planNames[plan.ID] = plan.Name
|
||||
}
|
||||
}
|
||||
|
||||
list := make([]gin.H, 0, len(users))
|
||||
for _, user := range users {
|
||||
@@ -191,32 +229,30 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
|
||||
}
|
||||
allowed := service.PluginUserAllowed(&user, user.Plan)
|
||||
status := "not_allowed"
|
||||
statusLabel := "Not eligible"
|
||||
if allowed {
|
||||
status = "eligible"
|
||||
statusLabel = "Ready to enable"
|
||||
planID := shadowPlanID
|
||||
planNameValue := planNames[shadowPlanID]
|
||||
if hasShadowUser {
|
||||
planID = intFromPointer(shadowUser.PlanID)
|
||||
planNameValue = planName(shadowUser.Plan)
|
||||
}
|
||||
shadowUserID := 0
|
||||
shadowUpdatedAt := int64(0)
|
||||
if hasSubscription {
|
||||
status = firstString(subscription.Status, status)
|
||||
statusLabel = "IPv6 enabled"
|
||||
if subscription.Status != "active" && subscription.Status != "" {
|
||||
statusLabel = strings.ReplaceAll(strings.Title(strings.ReplaceAll(subscription.Status, "_", " ")), "Ipv6", "IPv6")
|
||||
}
|
||||
if subscription.ShadowUserID != nil {
|
||||
shadowUserID = *subscription.ShadowUserID
|
||||
}
|
||||
shadowUpdatedAt = subscription.UpdatedAt
|
||||
} else if allowed {
|
||||
statusLabel = "Ready to enable"
|
||||
}
|
||||
effectiveAllowed := allowed || hasSubscription && subscription.Allowed
|
||||
status, statusLabel, _ := ipv6StatusPresentation(status, effectiveAllowed)
|
||||
|
||||
list = append(list, gin.H{
|
||||
"id": user.ID,
|
||||
"email": user.Email,
|
||||
"plan_name": planName(user.Plan),
|
||||
"allowed": allowed || hasSubscription && subscription.Allowed,
|
||||
"plan_id": planID,
|
||||
"plan_name": firstString(planNameValue, "-"),
|
||||
"allowed": effectiveAllowed,
|
||||
"is_active": hasSubscription && subscription.Status == "active",
|
||||
"status": status,
|
||||
"status_label": statusLabel,
|
||||
@@ -238,6 +274,71 @@ func AdminIPv6SubscriptionUsers(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func AdminIPv6SubscriptionConfigFetch(c *gin.Context) {
|
||||
cfg := service.GetPluginConfig(service.PluginUserAddIPv6)
|
||||
Success(c, gin.H{
|
||||
"ipv6_plan_id": parsePositiveInt(service.GetPluginConfigString(service.PluginUserAddIPv6, "ipv6_plan_id", "0"), 0),
|
||||
"allowed_plans": service.GetPluginConfigIntList(service.PluginUserAddIPv6, "allowed_plans"),
|
||||
"allowed_groups": service.GetPluginConfigIntList(service.PluginUserAddIPv6, "allowed_groups"),
|
||||
"email_suffix": firstString(stringFromAny(cfg["email_suffix"]), "-ipv6"),
|
||||
"reference_flag": firstString(stringFromAny(cfg["reference_flag"]), "ipv6"),
|
||||
})
|
||||
}
|
||||
|
||||
func AdminIPv6SubscriptionConfigSave(c *gin.Context) {
|
||||
var payload struct {
|
||||
IPv6PlanID int `json:"ipv6_plan_id"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||
Fail(c, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
var plugin model.Plugin
|
||||
err := database.DB.Where("code = ?", service.PluginUserAddIPv6).First(&plugin).Error
|
||||
if err != nil {
|
||||
plugin = model.Plugin{
|
||||
Code: service.PluginUserAddIPv6,
|
||||
Name: "IPv6 Subscription",
|
||||
IsEnabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
cfg := service.GetPluginConfig(service.PluginUserAddIPv6)
|
||||
if payload.IPv6PlanID > 0 {
|
||||
cfg["ipv6_plan_id"] = payload.IPv6PlanID
|
||||
} else {
|
||||
delete(cfg, "ipv6_plan_id")
|
||||
}
|
||||
|
||||
raw, marshalErr := json.Marshal(cfg)
|
||||
if marshalErr != nil {
|
||||
Fail(c, http.StatusInternalServerError, "failed to encode plugin config")
|
||||
return
|
||||
}
|
||||
configText := string(raw)
|
||||
plugin.Config = &configText
|
||||
|
||||
if plugin.ID > 0 {
|
||||
if updateErr := database.DB.Model(&model.Plugin{}).Where("id = ?", plugin.ID).Updates(map[string]any{
|
||||
"config": plugin.Config,
|
||||
"is_enabled": plugin.IsEnabled,
|
||||
}).Error; updateErr != nil {
|
||||
Fail(c, http.StatusInternalServerError, "failed to save plugin config")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if createErr := database.DB.Create(&plugin).Error; createErr != nil {
|
||||
Fail(c, http.StatusInternalServerError, "failed to create plugin config")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Success(c, gin.H{
|
||||
"ipv6_plan_id": payload.IPv6PlanID,
|
||||
})
|
||||
}
|
||||
|
||||
func AdminIPv6SubscriptionEnable(c *gin.Context) {
|
||||
userID := parsePositiveInt(c.Param("userId"), 0)
|
||||
if userID == 0 {
|
||||
@@ -346,24 +447,14 @@ func PluginUserAddIPv6Check(c *gin.Context) {
|
||||
hasSubscription := database.DB.Where("user_id = ?", user.ID).First(&subscription).Error == nil
|
||||
allowed := service.PluginUserAllowed(user, plan)
|
||||
status := "not_allowed"
|
||||
statusLabel := "Not eligible"
|
||||
reason := "Current plan or group is not allowed to enable IPv6"
|
||||
if allowed {
|
||||
status = "eligible"
|
||||
statusLabel = "Ready to enable"
|
||||
reason = ""
|
||||
}
|
||||
if hasSubscription {
|
||||
status = firstString(subscription.Status, "active")
|
||||
statusLabel = "IPv6 enabled"
|
||||
reason = ""
|
||||
if subscription.Status != "active" && subscription.Status != "" {
|
||||
statusLabel = strings.ReplaceAll(strings.Title(strings.ReplaceAll(subscription.Status, "_", " ")), "Ipv6", "IPv6")
|
||||
}
|
||||
}
|
||||
effectiveAllowed := allowed || hasSubscription && subscription.Allowed
|
||||
status, statusLabel, reason := ipv6StatusPresentation(status, effectiveAllowed)
|
||||
|
||||
Success(c, gin.H{
|
||||
"allowed": allowed || hasSubscription && subscription.Allowed,
|
||||
"allowed": effectiveAllowed,
|
||||
"is_active": hasSubscription && subscription.Status == "active",
|
||||
"status": status,
|
||||
"status_label": statusLabel,
|
||||
|
||||
Reference in New Issue
Block a user