feat(subscribe): 添加订阅关联服务器数量统计功能
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m38s

添加 ServerCount 字段到 Subscribe 类型中,并在查询订阅列表时统计关联的服务器数量
This commit is contained in:
shanshanzhong 2025-10-21 21:10:13 -07:00
parent b72523c837
commit 75c6adc178
13 changed files with 112 additions and 90 deletions

View File

@ -19,8 +19,8 @@ type (
Periods []TimePeriod `json:"periods"`
}
PreViewNodeMultiplierResponse {
CurrentTime string `json:"current_time"`
Ratio float32 `json:"ratio"`
CurrentTime string `json:"current_time"`
Ratio float32 `json:"ratio"`
}
)

View File

@ -16,7 +16,7 @@ type (
Password string `json:"password" validate:"required"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type"`
LoginType string `header:"Login-Type"`
CfToken string `json:"cf_token,optional"`
}
// Check user is exist request
@ -36,19 +36,19 @@ type (
Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type"`
LoginType string `header:"Login-Type"`
CfToken string `json:"cf_token,optional"`
}
// User login response
ResetPasswordRequest {
Identifier string `json:"identifier"`
Email string `json:"email" validate:"required"`
Password string `json:"password" validate:"required"`
Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type"`
CfToken string `json:"cf_token,optional"`
Identifier string `json:"identifier"`
Email string `json:"email" validate:"required"`
Password string `json:"password" validate:"required"`
Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type"`
CfToken string `json:"cf_token,optional"`
}
LoginResponse {
Token string `json:"token"`
@ -73,7 +73,7 @@ type (
Password string `json:"password"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type"`
LoginType string `header:"Login-Type"`
CfToken string `json:"cf_token,optional"`
}
// Check user is exist request
@ -95,19 +95,19 @@ type (
Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type,optional"`
LoginType string `header:"Login-Type,optional"`
CfToken string `json:"cf_token,optional"`
}
// User login response
TelephoneResetPasswordRequest {
Identifier string `json:"identifier"`
Identifier string `json:"identifier"`
Telephone string `json:"telephone" validate:"required"`
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
Password string `json:"password" validate:"required"`
Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
LoginType string `header:"Login-Type,optional"`
LoginType string `header:"Login-Type,optional"`
CfToken string `json:"cf_token,optional"`
}
AppleLoginCallbackRequest {
@ -128,9 +128,9 @@ type (
)
@server (
prefix: v1/auth
group: auth
middleware: DeviceMiddleware
prefix: v1/auth
group: auth
middleware: DeviceMiddleware
)
service ppanel {
@doc "User login"

View File

@ -90,9 +90,9 @@ type (
)
@server (
prefix: v1/common
group: common
middleware: DeviceMiddleware
prefix: v1/common
group: common
middleware: DeviceMiddleware
)
service ppanel {
@doc "Get global config"

View File

@ -68,9 +68,9 @@ type (
)
@server (
prefix: v1/public/portal
group: public/portal
middleware: DeviceMiddleware
prefix: v1/public/portal
group: public/portal
middleware: DeviceMiddleware
)
service ppanel {
@doc "Get available payment methods"

View File

@ -14,43 +14,40 @@ type (
QuerySubscribeListRequest {
Language string `form:"language"`
}
QueryUserSubscribeNodeListResponse {
List []UserSubscribeInfo `json:"list"`
}
UserSubscribeInfo {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
OrderId int64 `json:"order_id"`
SubscribeId int64 `json:"subscribe_id"`
StartTime int64 `json:"start_time"`
ExpireTime int64 `json:"expire_time"`
FinishedAt int64 `json:"finished_at"`
ResetTime int64 `json:"reset_time"`
Traffic int64 `json:"traffic"`
Download int64 `json:"download"`
Upload int64 `json:"upload"`
Token string `json:"token"`
Status uint8 `json:"status"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
IsTryOut bool `json:"is_try_out"`
Nodes []*UserSubscribeNodeInfo `json:"nodes"`
}
UserSubscribeNodeInfo{
Id int64 `json:"id"`
Name string `json:"name"`
Uuid string `json:"uuid"`
Protocol string `json:"protocol"`
Port uint16 `json:"port"`
Address string `json:"address"`
Tags []string `json:"tags"`
Country string `json:"country"`
City string `json:"city"`
CreatedAt int64 `json:"created_at"`
}
QueryUserSubscribeNodeListResponse {
List []UserSubscribeInfo `json:"list"`
}
UserSubscribeInfo {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
OrderId int64 `json:"order_id"`
SubscribeId int64 `json:"subscribe_id"`
StartTime int64 `json:"start_time"`
ExpireTime int64 `json:"expire_time"`
FinishedAt int64 `json:"finished_at"`
ResetTime int64 `json:"reset_time"`
Traffic int64 `json:"traffic"`
Download int64 `json:"download"`
Upload int64 `json:"upload"`
Token string `json:"token"`
Status uint8 `json:"status"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
IsTryOut bool `json:"is_try_out"`
Nodes []*UserSubscribeNodeInfo `json:"nodes"`
}
UserSubscribeNodeInfo {
Id int64 `json:"id"`
Name string `json:"name"`
Uuid string `json:"uuid"`
Protocol string `json:"protocol"`
Port uint16 `json:"port"`
Address string `json:"address"`
Tags []string `json:"tags"`
Country string `json:"country"`
City string `json:"city"`
CreatedAt int64 `json:"created_at"`
}
)
@server (
@ -63,8 +60,8 @@ service ppanel {
@handler QuerySubscribeList
get /list (QuerySubscribeListRequest) returns (QuerySubscribeListResponse)
@doc "Get user subscribe node info"
@handler QueryUserSubscribeNodeList
get /node/list returns (QueryUserSubscribeNodeListResponse)
@doc "Get user subscribe node info"
@handler QueryUserSubscribeNodeList
get /node/list returns (QueryUserSubscribeNodeListResponse)
}

View File

@ -97,15 +97,13 @@ type (
Email string `json:"email" validate:"required"`
Code string `json:"code" validate:"required"`
}
GetDeviceListResponse {
List []UserDevice `json:"list"`
Total int64 `json:"total"`
}
UnbindDeviceRequest {
Id int64 `json:"id" validate:"required"`
}
GetDeviceListResponse {
List []UserDevice `json:"list"`
Total int64 `json:"total"`
}
UnbindDeviceRequest {
Id int64 `json:"id" validate:"required"`
}
)
@server (
@ -202,12 +200,12 @@ service ppanel {
@handler UpdateBindEmail
put /bind_email (UpdateBindEmailRequest)
@doc "Get Device List"
@handler GetDeviceList
get /devices returns (GetDeviceListResponse)
@doc "Get Device List"
@handler GetDeviceList
get /devices returns (GetDeviceListResponse)
@doc "Unbind Device"
@handler UnbindDevice
put /unbind_device (UnbindDeviceRequest)
@doc "Unbind Device"
@handler UnbindDevice
put /unbind_device (UnbindDeviceRequest)
}

View File

@ -115,7 +115,7 @@ type (
AuthConfig {
Mobile MobileAuthenticateConfig `json:"mobile"`
Email EmailAuthticateConfig `json:"email"`
Device DeviceAuthticateConfig `json:"device"`
Device DeviceAuthticateConfig `json:"device"`
Register PubilcRegisterConfig `json:"register"`
}
PubilcRegisterConfig {
@ -135,14 +135,12 @@ type (
EnableDomainSuffix bool `json:"enable_domain_suffix"`
DomainSuffixList string `json:"domain_suffix_list"`
}
DeviceAuthticateConfig {
Enable bool `json:"enable"`
ShowAds bool `json:"show_ads"`
EnableSecurity bool `json:"enable_security"`
OnlyRealDevice bool `json:"only_real_device"`
}
DeviceAuthticateConfig {
Enable bool `json:"enable"`
ShowAds bool `json:"show_ads"`
EnableSecurity bool `json:"enable_security"`
OnlyRealDevice bool `json:"only_real_device"`
}
RegisterConfig {
StopRegister bool `json:"stop_register"`
EnableTrial bool `json:"enable_trial"`
@ -674,7 +672,6 @@ type (
List []SubscribeGroup `json:"list"`
Total int64 `json:"total"`
}
GetUserSubscribeTrafficLogsRequest {
Page int `form:"page"`
Size int `form:"size"`

View File

@ -56,6 +56,19 @@ func (l *QuerySubscribeListLogic) QuerySubscribeList(req *types.QuerySubscribeLi
list[i] = sub
}
list[i] = sub
// 通过服务组查询关联的节点数量
if item.ServerGroup != "" {
groupIds := tool.StringToInt64Slice(item.ServerGroup)
servers, err := l.svcCtx.ServerModel.FindServerListByGroupIds(l.ctx, groupIds)
if err != nil {
l.Errorw("[QuerySubscribeListLogic] FindServerListByGroupIds error", logger.Field("error", err.Error()))
sub.ServerCount = 0
} else {
sub.ServerCount = int64(len(servers))
}
} else {
sub.ServerCount = 0
}
}
resp.List = list
return

View File

@ -22,6 +22,7 @@ type Subscribe struct {
Quota int64 `gorm:"type:int;not null;default:0;comment:Quota"`
Nodes string `gorm:"type:varchar(255);comment:Node Ids"`
NodeTags string `gorm:"type:varchar(255);comment:Node Tags"`
ServerGroup string `gorm:"type:varchar(255);comment:Server Group"`
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"`

View File

@ -16,6 +16,7 @@ import (
"github.com/perfect-panel/server/internal/model/log"
"github.com/perfect-panel/server/internal/model/order"
"github.com/perfect-panel/server/internal/model/payment"
"github.com/perfect-panel/server/internal/model/server"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/server/internal/model/system"
"github.com/perfect-panel/server/internal/model/ticket"
@ -47,6 +48,7 @@ type ServiceContext struct {
TicketModel ticket.Model
//ServerModel server.Model
SystemModel system.Model
ServerModel server.Model
CouponModel coupon.Model
PaymentModel payment.Model
DocumentModel document.Model
@ -98,6 +100,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
TicketModel: ticket.NewModel(db, rds),
//ServerModel: server.NewModel(db, rds),
SystemModel: system.NewModel(db, rds),
ServerModel: server.NewModel(db, rds),
CouponModel: coupon.NewModel(db, rds),
PaymentModel: payment.NewModel(db, rds),
DocumentModel: document.NewModel(db, rds),

View File

@ -2020,6 +2020,7 @@ type Subscribe struct {
Quota int64 `json:"quota"`
Nodes []int64 `json:"nodes"`
NodeTags []string `json:"node_tags"`
ServerCount int64 `json:"server_count"`
Show bool `json:"show"`
Sell bool `json:"sell"`
Sort int64 `json:"sort"`

View File

@ -10,11 +10,15 @@ if [[ "$OS_TYPE" == "Linux" ]]; then
./generate/gopure-linux-amd64 api format --dir ./apis
echo "Architecture: amd64"
./generate/gopure-linux-amd64 api go -api *.api -dir . -style goZero
echo "Generate Swagger JSON documentation"
./generate/gopure-linux-amd64 api plugin -plugin goctl-swagger="swagger -filename ppanel.json -host localhost:8080 -basepath /" -api ppanel.api -dir .
elif [[ "$ARCH_TYPE" == "aarch64" ]]; then
echo "Format api file"
./generate/gopure-linux-arm64 api format --dir ./apis
echo "Architecture: arm64"
./generate/gopure-linux-arm64 api go -api *.api -dir . -style goZero
echo "Generate Swagger JSON documentation"
./generate/gopure-linux-arm64 api plugin -plugin goctl-swagger="swagger -filename ppanel.json -host localhost:8080 -basepath /" -api ppanel.api -dir .
else
echo "Unrecognized architecture: $ARCH_TYPE"
fi
@ -25,11 +29,15 @@ elif [[ "$OS_TYPE" == "Darwin" ]]; then
./generate/gopure-darwin-amd64 api format --dir ./apis
echo "Architecture: amd64"
./generate/gopure-darwin-amd64 api go -api *.api -dir . -style goZero
echo "Generate Swagger JSON documentation"
./generate/gopure-darwin-amd64 api plugin -plugin goctl-swagger="swagger -filename ppanel.json -host localhost:8080 -basepath /" -api ppanel.api -dir .
elif [[ "$ARCH_TYPE" == "arm64" ]]; then
echo "Format api file"
./generate/gopure-darwin-arm64 api format --dir ./apis
echo "Architecture: arm64"
./generate/gopure-darwin-arm64 api go -api *.api -dir . -style goZero
echo "Generate Swagger JSON documentation"
./generate/gopure-darwin-arm64 api plugin -plugin goctl-swagger="swagger -filename ppanel.json -host localhost:8080 -basepath /" -api ppanel.api -dir .
else
echo "Unrecognized architecture: $ARCH_TYPE"
fi
@ -40,11 +48,15 @@ elif [[ "$OS_TYPE" == "CYGWIN"* || "$OS_TYPE" == "MINGW"* ]]; then
./generate/gopure-amd64.exe api format --dir ./apis
echo "Architecture: amd64"
./generate/gopure-amd64.exe api go -api *.api -dir . -style goZero
echo "Generate Swagger JSON documentation"
./generate/gopure-amd64.exe api plugin -plugin goctl-swagger="swagger -filename ppanel.json -host localhost:8080 -basepath /" -api ppanel.api -dir .
elif [[ "$ARCH_TYPE" == "arm64" ]]; then
echo "Format api file"
./generate/gopure-arm64.exe api format --dir ./apis
echo "Architecture: arm64"
./generate/gopure-arm64.exe api go -api *.api -dir . -style goZero
echo "Generate Swagger JSON documentation"
./generate/gopure-arm64.exe api plugin -plugin goctl-swagger="swagger -filename ppanel.json -host localhost:8080 -basepath /" -api ppanel.api -dir .
else
echo "Unrecognized architecture: $ARCH_TYPE"
fi

BIN
server

Binary file not shown.