分组概念
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m58s
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m58s
This commit is contained in:
parent
e5e9f93f68
commit
f703b5089a
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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"`
|
||||
|
||||
@ -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"`
|
||||
|
||||
@ -134,6 +134,11 @@ const (
|
||||
DeviceBindLimitExceeded uint32 = 90019
|
||||
)
|
||||
|
||||
// Permission error
|
||||
const (
|
||||
PermissionDenied uint32 = 40300
|
||||
)
|
||||
|
||||
const (
|
||||
OrderNotExist uint32 = 61001
|
||||
PaymentMethodNotFound uint32 = 61002
|
||||
|
||||
@ -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",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user