diff --git a/etc/ppanel.yaml b/etc/ppanel.yaml index 0ecc9bd..d19d1f7 100644 --- a/etc/ppanel.yaml +++ b/etc/ppanel.yaml @@ -15,10 +15,10 @@ Logger: # 日志配置 Level: debug # 日志级别: debug, info, warn, error, panic, fatal MySQL: - Addr: 103.150.215.44:3306 # host 网络模式; bridge 模式改为 mysql:3306 + Addr: 154.12.35.103:3306 # host 网络模式; bridge 模式改为 mysql:3306 Username: root # MySQL用户名 Password: jpcV41ppanel # MySQL密码,与 .env MYSQL_ROOT_PASSWORD 一致 - Dbname: hifast # MySQL数据库名 + Dbname: ppanel # MySQL数据库名 Config: charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai MaxIdleConns: 10 MaxOpenConns: 100 diff --git a/initialize/migrate/database/02131_add_groups.down.sql b/initialize/migrate/database/02142_add_groups.down.sql similarity index 100% rename from initialize/migrate/database/02131_add_groups.down.sql rename to initialize/migrate/database/02142_add_groups.down.sql diff --git a/initialize/migrate/database/02131_add_groups.up.sql b/initialize/migrate/database/02142_add_groups.up.sql similarity index 100% rename from initialize/migrate/database/02131_add_groups.up.sql rename to initialize/migrate/database/02142_add_groups.up.sql diff --git a/initialize/migrate/database/02132_update_verify_config.down.sql b/initialize/migrate/database/02143_update_verify_config.down.sql similarity index 100% rename from initialize/migrate/database/02132_update_verify_config.down.sql rename to initialize/migrate/database/02143_update_verify_config.down.sql diff --git a/initialize/migrate/database/02132_update_verify_config.up.sql b/initialize/migrate/database/02143_update_verify_config.up.sql similarity index 100% rename from initialize/migrate/database/02132_update_verify_config.up.sql rename to initialize/migrate/database/02143_update_verify_config.up.sql diff --git a/initialize/migrate/database/02133_add_expired_node_group.down.sql b/initialize/migrate/database/02144_add_expired_node_group.down.sql similarity index 100% rename from initialize/migrate/database/02133_add_expired_node_group.down.sql rename to initialize/migrate/database/02144_add_expired_node_group.down.sql diff --git a/initialize/migrate/database/02133_add_expired_node_group.up.sql b/initialize/migrate/database/02144_add_expired_node_group.up.sql similarity index 100% rename from initialize/migrate/database/02133_add_expired_node_group.up.sql rename to initialize/migrate/database/02144_add_expired_node_group.up.sql diff --git a/initialize/migrate/database/02134_subscribe_traffic_limit.down.sql b/initialize/migrate/database/02145_subscribe_traffic_limit.down.sql similarity index 100% rename from initialize/migrate/database/02134_subscribe_traffic_limit.down.sql rename to initialize/migrate/database/02145_subscribe_traffic_limit.down.sql diff --git a/initialize/migrate/database/02134_subscribe_traffic_limit.up.sql b/initialize/migrate/database/02145_subscribe_traffic_limit.up.sql similarity index 100% rename from initialize/migrate/database/02134_subscribe_traffic_limit.up.sql rename to initialize/migrate/database/02145_subscribe_traffic_limit.up.sql diff --git a/internal/handler/auth/telephoneLoginHandler.go b/internal/handler/auth/telephoneLoginHandler.go index 8319352..13352c7 100644 --- a/internal/handler/auth/telephoneLoginHandler.go +++ b/internal/handler/auth/telephoneLoginHandler.go @@ -1,11 +1,16 @@ package auth import ( + "time" + "github.com/gin-gonic/gin" "github.com/perfect-panel/server/internal/logic/auth" "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/pkg/result" + "github.com/perfect-panel/server/pkg/turnstile" + "github.com/perfect-panel/server/pkg/xerr" + "github.com/pkg/errors" ) // User Telephone login diff --git a/internal/logic/public/subscribe/queryUserSubscribeNodeListLogic.go b/internal/logic/public/subscribe/queryUserSubscribeNodeListLogic.go index 0e25486..87773fe 100644 --- a/internal/logic/public/subscribe/queryUserSubscribeNodeListLogic.go +++ b/internal/logic/public/subscribe/queryUserSubscribeNodeListLogic.go @@ -6,6 +6,7 @@ import ( "time" commonLogic "github.com/perfect-panel/server/internal/logic/common" + "github.com/perfect-panel/server/internal/model/group" "github.com/perfect-panel/server/internal/model/node" "github.com/perfect-panel/server/internal/model/user" "github.com/perfect-panel/server/internal/svc" @@ -117,20 +118,24 @@ func (l *QueryUserSubscribeNodeListLogic) getServers(userSub *user.Subscribe) (u l.Debugw("[GetServers] Failed to check group enabled", logger.Field("error", err.Error())) // Continue with tag-based filtering } - nodeIds := tool.StringToInt64Slice(subDetails.Nodes) - tags := normalizeSubscribeNodeTags(subDetails.NodeTags) - isGroupEnabled := (groupEnabled == "true" || groupEnabled == "1") - enable := true - - _, nodes, err := l.svcCtx.NodeModel.FilterNodeList(l.ctx, &node.FilterNodeParams{ - Page: 1, - Size: 1000, - NodeId: nodeIds, - Tag: tags, - Enabled: &enable, // Only get enabled nodes - }) + var nodes []*node.Node + if isGroupEnabled { + // Group mode: use group_ids to filter nodes + nodes, err = l.getNodesByGroup(userSub) + if err != nil { + l.Errorw("[GetServers] Failed to get nodes by group", logger.Field("error", err.Error())) + return nil, err + } + } else { + // Tag mode: use node_ids and tags to filter nodes + nodes, err = l.getNodesByTag(userSub) + if err != nil { + l.Errorw("[GetServers] Failed to get nodes by tag", logger.Field("error", err.Error())) + return nil, err + } + } // Process nodes and create response if len(nodes) > 0 { diff --git a/internal/model/subscribe/subscribe.go b/internal/model/subscribe/subscribe.go index 49cbcc6..7ac9da4 100644 --- a/internal/model/subscribe/subscribe.go +++ b/internal/model/subscribe/subscribe.go @@ -68,9 +68,12 @@ type Subscribe struct { DeviceLimit int64 `gorm:"type:int;not null;default:0;comment:Device Limit"` Quota int64 `gorm:"type:int;not null;default:0;comment:Quota"` NewUserOnly *bool `gorm:"type:tinyint(1);default:0;comment:New user only: allow purchase within 24h of registration, once per user"` - Nodes string `gorm:"type:varchar(255);comment:Node Ids"` - NodeTags string `gorm:"type:varchar(255);comment:Node Tags"` - Show *bool `gorm:"type:tinyint(1);not null;default:0;comment:Show portal page"` + Nodes string `gorm:"type:varchar(255);comment:Node Ids"` + NodeTags string `gorm:"type:varchar(255);comment:Node Tags"` + NodeGroupIds JSONInt64Slice `gorm:"type:json;comment:Node Group IDs (JSON array, multiple groups)"` + NodeGroupId int64 `gorm:"default:0;index:idx_node_group_id;comment:Default Node Group ID (single ID)"` + TrafficLimit string `gorm:"type:text;comment:Traffic Limit Rules"` + Show *bool `gorm:"type:tinyint(1);not null;default:0;comment:Show portal page"` Sell *bool `gorm:"type:tinyint(1);not null;default:0;comment:Sell"` Sort int64 `gorm:"type:int;not null;default:0;comment:Sort"` DeductionRatio int64 `gorm:"type:int;default:0;comment:Deduction Ratio"` diff --git a/internal/types/types.go b/internal/types/types.go index 919e483..67752c4 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -561,6 +561,13 @@ type DeleteAccountResponse struct { Code int64 `json:"code"` } +type DailyTrafficStats struct { + Date string `json:"date"` + Upload int64 `json:"upload"` + Download int64 `json:"download"` + Total int64 `json:"total"` +} + type DeleteAdsRequest struct { Id int64 `json:"id"` } @@ -681,6 +688,10 @@ type EmailAuthticateConfig struct { DomainSuffixList string `json:"domain_suffix_list"` } +type ExportGroupResultRequest struct { + HistoryId *int64 `form:"history_id,omitempty"` +} + type ErrorLogMessage struct { Id int64 `json:"id"` Platform string `json:"platform"` @@ -1114,6 +1125,37 @@ type GetInviteSalesResponse struct { List []InvitedUserSale `json:"list"` } +type GetGroupConfigRequest struct { + Keys []string `form:"keys,omitempty"` +} + +type GetGroupConfigResponse struct { + Enabled bool `json:"enabled"` + Mode string `json:"mode"` + Config map[string]interface{} `json:"config"` + State RecalculationState `json:"state"` +} + +type GetGroupHistoryDetailRequest struct { + Id int64 `form:"id" validate:"required"` +} + +type GetGroupHistoryDetailResponse struct { + GroupHistoryDetail +} + +type GetGroupHistoryRequest struct { + Page int `form:"page"` + Size int `form:"size"` + GroupMode string `form:"group_mode,omitempty"` + TriggerType string `form:"trigger_type,omitempty"` +} + +type GetGroupHistoryResponse struct { + Total int64 `json:"total"` + List []GroupHistory `json:"list"` +} + type GetLoginLogRequest struct { Page int `form:"page"` Size int `form:"size"` @@ -2881,6 +2923,26 @@ type UpdateFamilyMaxMembersRequest struct { MaxMembers int64 `json:"max_members" validate:"required,gt=0"` } +type UpdateGroupConfigRequest struct { + Enabled bool `json:"enabled"` + Mode string `json:"mode"` + Config map[string]interface{} `json:"config"` +} + +type UpdateNodeGroupRequest struct { + Id int64 `json:"id" validate:"required"` + Name string `json:"name"` + Description string `json:"description"` + Sort int `json:"sort"` + ForCalculation *bool `json:"for_calculation"` + IsExpiredGroup *bool `json:"is_expired_group"` + ExpiredDaysLimit *int `json:"expired_days_limit"` + MaxTrafficGBExpired *int64 `json:"max_traffic_gb_expired,omitempty"` + SpeedLimit *int `json:"speed_limit"` + MinTrafficGB *int64 `json:"min_traffic_gb,omitempty"` + MaxTrafficGB *int64 `json:"max_traffic_gb,omitempty"` +} + type UpdateNodeRequest struct { Id int64 `json:"id"` Name string `json:"name"` @@ -3171,6 +3233,7 @@ type UserStatisticsResponse struct { type UserSubscribe struct { Id int64 `json:"id"` + IdStr string `json:"id_str"` UserId int64 `json:"user_id"` OrderId int64 `json:"order_id"` SubscribeId int64 `json:"subscribe_id"` diff --git a/pkg/xerr/errCode.go b/pkg/xerr/errCode.go index 28c104a..e334a71 100644 --- a/pkg/xerr/errCode.go +++ b/pkg/xerr/errCode.go @@ -134,6 +134,11 @@ const ( DeviceBindLimitExceeded uint32 = 90019 ) +// Permission error +const ( + PermissionDenied uint32 = 40300 +) + const ( OrderNotExist uint32 = 61001 PaymentMethodNotFound uint32 = 61002 diff --git a/pkg/xerr/errMsg.go b/pkg/xerr/errMsg.go index f235187..3889559 100644 --- a/pkg/xerr/errMsg.go +++ b/pkg/xerr/errMsg.go @@ -102,6 +102,9 @@ func init() { PaymentMethodNotFound: "Payment method not found", OrderStatusError: "Order status error", InsufficientOfPeriod: "Insufficient number of period", + + // Permission error + PermissionDenied: "Permission denied", } }