Compare commits

..

No commits in common. "master" and "v1.0.5" have entirely different histories.

363 changed files with 12156 additions and 9275 deletions

View File

@ -35,6 +35,7 @@ jobs:
mkdir -p swagger mkdir -p swagger
goctl api plugin -plugin goctl-swagger='swagger -filename common.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_common.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename common.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_common.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename user.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_user.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename user.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_user.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename app.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_app.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename admin.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_admin.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename admin.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_admin.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename ppanel.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ppanel.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename ppanel.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ppanel.api -dir ./swagger
goctl api plugin -plugin goctl-swagger='swagger -filename node.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_node.api -dir ./swagger goctl api plugin -plugin goctl-swagger='swagger -filename node.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_node.api -dir ./swagger
@ -44,6 +45,7 @@ jobs:
run: | run: |
test -f ./swagger/common.json test -f ./swagger/common.json
test -f ./swagger/user.json test -f ./swagger/user.json
test -f ./swagger/app.json
test -f ./swagger/admin.json test -f ./swagger/admin.json
- name: Checkout target repository - name: Checkout target repository

View File

@ -3,6 +3,9 @@
<module name="server" /> <module name="server" />
<working_directory value="$PROJECT_DIR$" /> <working_directory value="$PROJECT_DIR$" />
<parameters value="run --config etc/ppanel-dev.yaml" /> <parameters value="run --config etc/ppanel-dev.yaml" />
<envs>
<env name="PPANEL_MODE" value="demo" />
</envs>
<kind value="PACKAGE" /> <kind value="PACKAGE" />
<package value="github.com/perfect-panel/server" /> <package value="github.com/perfect-panel/server" />
<directory value="$PROJECT_DIR$" /> <directory value="$PROJECT_DIR$" />

View File

@ -14,19 +14,6 @@
</div> </div>
> **Article 1.**
> All human beings are born free and equal in dignity and rights.
> They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.
>
> **Article 12.**
> No one shall be subjected to arbitrary interference with his privacy, family, home or correspondence, nor to attacks upon his honour and reputation.
> Everyone has the right to the protection of the law against such interference or attacks.
>
> **Article 19.**
> Everyone has the right to freedom of opinion and expression; this right includes freedom to hold opinions without interference and to seek, receive and impart information and ideas through any media and regardless of frontiers.
>
> *Source: [United Nations Universal Declaration of Human Rights (UN.org)](https://www.un.org/sites/un2.un.org/files/2021/03/udhr.pdf)*
## 📋 Overview ## 📋 Overview
PPanel Server is the backend component of the PPanel project, providing robust APIs and core functionality for managing PPanel Server is the backend component of the PPanel project, providing robust APIs and core functionality for managing

View File

@ -1,25 +1,26 @@
package adapter package adapter
import ( import (
"strings" "encoding/json"
"github.com/perfect-panel/server/internal/model/node" "github.com/perfect-panel/server/internal/model/server"
"github.com/perfect-panel/server/pkg/logger" "github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/random"
) )
type Adapter struct { type Adapter struct {
SiteName string // 站点名称 SiteName string // 站点名称
Servers []*node.Node // 服务器列表 Servers []*server.Server // 服务器列表
UserInfo User // 用户信息 UserInfo User // 用户信息
ClientTemplate string // 客户端配置模板 ClientTemplate string // 客户端配置模板
OutputFormat string // 输出格式,默认是 base64 OutputFormat string // 输出格式,默认是 base64
SubscribeName string // 订阅名称 SubscribeName string // 订阅名称
} }
type Option func(*Adapter) type Option func(*Adapter)
// WithServers 设置服务器列表 // WithServers 设置服务器列表
func WithServers(servers []*node.Node) Option { func WithServers(servers []*server.Server) Option {
return func(opts *Adapter) { return func(opts *Adapter) {
opts.Servers = servers opts.Servers = servers
} }
@ -55,7 +56,7 @@ func WithSubscribeName(name string) Option {
func NewAdapter(tpl string, opts ...Option) *Adapter { func NewAdapter(tpl string, opts ...Option) *Adapter {
adapter := &Adapter{ adapter := &Adapter{
Servers: []*node.Node{}, Servers: []*server.Server{},
UserInfo: User{}, UserInfo: User{},
ClientTemplate: tpl, ClientTemplate: tpl,
OutputFormat: "base64", // 默认输出格式 OutputFormat: "base64", // 默认输出格式
@ -86,55 +87,51 @@ func (adapter *Adapter) Client() (*Client, error) {
return client, nil return client, nil
} }
func (adapter *Adapter) Proxies(servers []*node.Node) ([]Proxy, error) { func (adapter *Adapter) Proxies(servers []*server.Server) ([]Proxy, error) {
var proxies []Proxy var proxies []Proxy
for _, srv := range servers {
for _, item := range servers { switch srv.RelayMode {
if item.Server == nil { case server.RelayModeAll:
logger.Errorf("[Adapter] Server is nil for node ID: %d", item.Id) var relays []server.NodeRelay
continue if err := json.Unmarshal([]byte(srv.RelayNode), &relays); err != nil {
} logger.Errorw("Unmarshal RelayNode", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", srv.RelayNode))
protocols, err := item.Server.UnmarshalProtocols() continue
if err != nil { }
logger.Errorf("[Adapter] Unmarshal Protocols error: %s; server id : %d", err.Error(), item.ServerId) for _, relay := range relays {
continue proxy, err := adapterProxy(*srv, relay.Host, uint64(relay.Port))
} if err != nil {
for _, protocol := range protocols { logger.Errorw("Adapter Proxy", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", relay))
if protocol.Type == item.Protocol { continue
proxies = append(proxies, Proxy{ }
Sort: item.Sort, proxies = append(proxies, proxy)
Name: item.Name,
Server: item.Address,
Port: item.Port,
Type: item.Protocol,
Tags: strings.Split(item.Tags, ","),
Security: protocol.Security,
SNI: protocol.SNI,
AllowInsecure: protocol.AllowInsecure,
Fingerprint: protocol.Fingerprint,
RealityServerAddr: protocol.RealityServerAddr,
RealityServerPort: protocol.RealityServerPort,
RealityPrivateKey: protocol.RealityPrivateKey,
RealityPublicKey: protocol.RealityPublicKey,
RealityShortId: protocol.RealityShortId,
Transport: protocol.Transport,
Host: protocol.Host,
Path: protocol.Path,
ServiceName: protocol.ServiceName,
Method: protocol.Cipher,
ServerKey: protocol.ServerKey,
Flow: protocol.Flow,
HopPorts: protocol.HopPorts,
HopInterval: protocol.HopInterval,
ObfsPassword: protocol.ObfsPassword,
DisableSNI: protocol.DisableSNI,
ReduceRtt: protocol.ReduceRtt,
UDPRelayMode: protocol.UDPRelayMode,
CongestionController: protocol.CongestionController,
})
} }
}
}
case server.RelayModeRandom:
var relays []server.NodeRelay
if err := json.Unmarshal([]byte(srv.RelayNode), &relays); err != nil {
logger.Errorw("Unmarshal RelayNode", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", srv.RelayNode))
continue
}
randNum := random.RandomInRange(0, len(relays)-1)
relay := relays[randNum]
proxy, err := adapterProxy(*srv, relay.Host, uint64(relay.Port))
if err != nil {
logger.Errorw("Adapter Proxy", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("relayNode", relay))
continue
}
proxies = append(proxies, proxy)
case server.RelayModeNone:
proxy, err := adapterProxy(*srv, srv.ServerAddr, 0)
if err != nil {
logger.Errorw("Adapter Proxy", logger.Field("error", err.Error()), logger.Field("node", srv.Name), logger.Field("serverAddr", srv.ServerAddr))
continue
}
proxies = append(proxies, proxy)
default:
logger.Errorw("Unknown RelayMode", logger.Field("node", srv.Name), logger.Field("relayMode", srv.RelayMode))
}
}
return proxies, nil return proxies, nil
} }

View File

@ -11,10 +11,9 @@ import (
) )
type Proxy struct { type Proxy struct {
Sort int
Name string Name string
Server string Server string
Port uint16 Port uint64
Type string Type string
Tags []string Tags []string
@ -36,46 +35,18 @@ type Proxy struct {
// Shadowsocks Options // Shadowsocks Options
Method string Method string
ServerKey string // For Shadowsocks 2022 ServerKey string // For Shadowsocks 2022
// Vmess/Vless/Trojan Options // Vmess/Vless/Trojan Options
Flow string // Flow for Vmess/Vless/Trojan Flow string // Flow for Vmess/Vless/Trojan
// Hysteria2 Options // Hysteria2 Options
HopPorts string // Comma-separated list of hop ports HopPorts string // Comma-separated list of hop ports
HopInterval int // Interval for hop ports in seconds HopInterval int // Interval for hop ports in seconds
ObfsPassword string // Obfuscation password for Hysteria2 ObfsPassword string // Obfuscation password for Hysteria2
UpMbps int // Upload speed in Mbps
DownMbps int // Download speed in Mbps
// Tuic Options // Tuic Options
DisableSNI bool // Disable SNI DisableSNI bool // Disable SNI
ReduceRtt bool // Reduce RTT ReduceRtt bool // Reduce RTT
UDPRelayMode string // UDP relay mode (e.g., "full", "partial") UDPRelayMode string // UDP relay mode (e.g., "full", "partial")
CongestionController string // Congestion controller (e.g., "cubic", "bbr") CongestionController string // Congestion controller (e.g., "cubic", "bbr")
// AnyTLS
PaddingScheme string
// Mieru
Multiplex string
// Obfs
Obfs string // obfs, 'none', 'http', 'tls'
ObfsHost string // obfs host
ObfsPath string // obfs path
// Vless
XhttpMode string // xhttp mode
XhttpExtra string // xhttp path
// encryption
Encryption string // encryption'none', 'mlkem768x25519plus'
EncryptionMode string // encryption mode'native', 'xorpub', 'random'
EncryptionRtt string // encryption rtt'0rtt', '1rtt'
EncryptionTicket string // encryption ticket
EncryptionServerPadding string // encryption server padding
EncryptionPrivateKey string // encryption private key
EncryptionClientPadding string // encryption client padding
EncryptionPassword string // encryption password
} }
type User struct { type User struct {

View File

@ -1 +1,113 @@
package adapter package adapter
import (
"encoding/json"
"fmt"
"strings"
"github.com/perfect-panel/server/internal/model/server"
"github.com/perfect-panel/server/pkg/tool"
)
func adapterProxy(svr server.Server, host string, port uint64) (Proxy, error) {
tags := strings.Split(svr.Tags, ",")
if len(tags) > 0 {
tags = tool.RemoveDuplicateElements(tags...)
}
node := Proxy{
Name: svr.Name,
Host: host,
Port: port,
Type: svr.Protocol,
Tags: tags,
}
switch svr.Protocol {
case "shadowsocks":
var ss server.Shadowsocks
if err := json.Unmarshal([]byte(svr.Config), &ss); err != nil {
return node, fmt.Errorf("unmarshal shadowsocks config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(ss.Port)
}
node.Method = ss.Method
node.ServerKey = ss.ServerKey
case "vless":
var vless server.Vless
if err := json.Unmarshal([]byte(svr.Config), &vless); err != nil {
return node, fmt.Errorf("unmarshal vless config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(vless.Port)
}
node.Flow = vless.Flow
node.Transport = vless.Transport
tool.DeepCopy(&node, vless.TransportConfig)
node.Security = vless.Security
tool.DeepCopy(&node, vless.SecurityConfig)
case "vmess":
var vmess server.Vmess
if err := json.Unmarshal([]byte(svr.Config), &vmess); err != nil {
return node, fmt.Errorf("unmarshal vmess config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(vmess.Port)
}
node.Flow = vmess.Flow
node.Transport = vmess.Transport
tool.DeepCopy(&node, vmess.TransportConfig)
node.Security = vmess.Security
tool.DeepCopy(&node, vmess.SecurityConfig)
case "trojan":
var trojan server.Trojan
if err := json.Unmarshal([]byte(svr.Config), &trojan); err != nil {
return node, fmt.Errorf("unmarshal trojan config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(trojan.Port)
}
node.Flow = trojan.Flow
node.Transport = trojan.Transport
tool.DeepCopy(&node, trojan.TransportConfig)
node.Security = trojan.Security
tool.DeepCopy(&node, trojan.SecurityConfig)
case "hysteria2":
var hysteria2 server.Hysteria2
if err := json.Unmarshal([]byte(svr.Config), &hysteria2); err != nil {
return node, fmt.Errorf("unmarshal hysteria2 config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(hysteria2.Port)
}
node.HopPorts = hysteria2.HopPorts
node.HopInterval = hysteria2.HopInterval
node.ObfsPassword = hysteria2.ObfsPassword
tool.DeepCopy(&node, hysteria2.SecurityConfig)
case "tuic":
var tuic server.Tuic
if err := json.Unmarshal([]byte(svr.Config), &tuic); err != nil {
return node, fmt.Errorf("unmarshal tuic config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(tuic.Port)
}
node.DisableSNI = tuic.DisableSNI
node.ReduceRtt = tuic.ReduceRtt
node.UDPRelayMode = tuic.UDPRelayMode
node.CongestionController = tuic.CongestionController
case "anytls":
var anytls server.AnyTLS
if err := json.Unmarshal([]byte(svr.Config), &anytls); err != nil {
return node, fmt.Errorf("unmarshal anytls config: %v", err.Error())
}
if port == 0 {
node.Port = uint64(anytls.Port)
}
tool.DeepCopy(&node, anytls.SecurityConfig)
default:
return node, fmt.Errorf("unsupported protocol: %s", svr.Protocol)
}
return node, nil
}

View File

@ -21,7 +21,7 @@ type (
Download int64 `json:"download"` Download int64 `json:"download"`
} }
ServerTotalDataResponse { ServerTotalDataResponse {
OnlineUsers int64 `json:"online_users"` OnlineUserIPs int64 `json:"online_user_ips"`
OnlineServers int64 `json:"online_servers"` OnlineServers int64 `json:"online_servers"`
OfflineServers int64 `json:"offline_servers"` OfflineServers int64 `json:"offline_servers"`
TodayUpload int64 `json:"today_upload"` TodayUpload int64 `json:"today_upload"`

View File

@ -12,184 +12,19 @@ import "../types.api"
type ( type (
GetMessageLogListRequest { GetMessageLogListRequest {
Page int `form:"page"` Page int `form:"page"`
Size int `form:"size"` Size int `form:"size"`
Type uint8 `form:"type"` Type string `form:"type"`
Search string `form:"search,optional"` Platform string `form:"platform,omitempty"`
To string `form:"to,omitempty"`
Subject string `form:"subject,omitempty"`
Content string `form:"content,omitempty"`
Status int `form:"status,omitempty"`
} }
GetMessageLogListResponse { GetMessageLogListResponse {
Total int64 `json:"total"` Total int64 `json:"total"`
List []MessageLog `json:"list"` List []MessageLog `json:"list"`
} }
FilterLogParams {
Page int `form:"page"`
Size int `form:"size"`
Date string `form:"date,optional"`
Search string `form:"search,optional"`
}
FilterEmailLogResponse {
Total int64 `json:"total"`
List []MessageLog `json:"list"`
}
FilterMobileLogResponse {
Total int64 `json:"total"`
List []MessageLog `json:"list"`
}
SubscribeLog {
UserId int64 `json:"user_id"`
Token string `json:"token"`
UserAgent string `json:"user_agent"`
ClientIP string `json:"client_ip"`
UserSubscribeId int64 `json:"user_subscribe_id"`
Timestamp int64 `json:"timestamp"`
}
FilterSubscribeLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
UserSubscribeId int64 `form:"user_subscribe_id,optional"`
}
FilterSubscribeLogResponse {
Total int64 `json:"total"`
List []SubscribeLog `json:"list"`
}
LoginLog {
UserId int64 `json:"user_id"`
Method string `json:"method"`
LoginIP string `json:"login_ip"`
UserAgent string `json:"user_agent"`
Success bool `json:"success"`
Timestamp int64 `json:"timestamp"`
}
FilterLoginLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterLoginLogResponse {
Total int64 `json:"total"`
List []LoginLog `json:"list"`
}
RegisterLog {
UserId int64 `json:"user_id"`
AuthMethod string `json:"auth_method"`
Identifier string `json:"identifier"`
RegisterIP string `json:"register_ip"`
UserAgent string `json:"user_agent"`
Timestamp int64 `json:"timestamp"`
}
FilterRegisterLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterRegisterLogResponse {
Total int64 `json:"total"`
List []RegisterLog `json:"list"`
}
ResetSubscribeLog {
Type uint16 `json:"type"`
UserId int64 `json:"user_id"`
UserSubscribeId int64 `json:"user_subscribe_id"`
OrderNo string `json:"order_no,omitempty"`
Timestamp int64 `json:"timestamp"`
}
FilterResetSubscribeLogRequest {
FilterLogParams
UserSubscribeId int64 `form:"user_subscribe_id,optional"`
}
FilterResetSubscribeLogResponse {
Total int64 `json:"total"`
List []ResetSubscribeLog `json:"list"`
}
UserSubscribeTrafficLog {
SubscribeId int64 `json:"subscribe_id"` // Subscribe ID
UserId int64 `json:"user_id"` // User ID
Upload int64 `json:"upload"` // Upload traffic in bytes
Download int64 `json:"download"` // Download traffic in bytes
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
Date string `json:"date"` // Date in YYYY-MM-DD format
Details bool `json:"details"` // Whether to show detailed traffic
}
FilterSubscribeTrafficRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
UserSubscribeId int64 `form:"user_subscribe_id,optional"`
}
FilterSubscribeTrafficResponse {
Total int64 `json:"total"`
List []UserSubscribeTrafficLog `json:"list"`
}
ServerTrafficLog {
ServerId int64 `json:"server_id"` // Server ID
Upload int64 `json:"upload"` // Upload traffic in bytes
Download int64 `json:"download"` // Download traffic in bytes
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
Date string `json:"date"` // Date in YYYY-MM-DD format
Details bool `json:"details"` // Whether to show detailed traffic
}
FilterServerTrafficLogRequest {
FilterLogParams
ServerId int64 `form:"server_id,optional"`
}
FilterServerTrafficLogResponse {
Total int64 `json:"total"`
List []ServerTrafficLog `json:"list"`
}
FilterBalanceLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterBalanceLogResponse {
Total int64 `json:"total"`
List []BalanceLog `json:"list"`
}
FilterCommissionLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterCommissionLogResponse {
Total int64 `json:"total"`
List []CommissionLog `json:"list"`
}
GiftLog {
Type uint16 `json:"type"`
userId int64 `json:"user_id"`
OrderNo string `json:"order_no"`
SubscribeId int64 `json:"subscribe_id"`
Amount int64 `json:"amount"`
Balance int64 `json:"balance"`
Remark string `json:"remark,omitempty"`
Timestamp int64 `json:"timestamp"`
}
FilterGiftLogRequest {
FilterLogParams
UserId int64 `form:"user_id,optional"`
}
FilterGiftLogResponse {
Total int64 `json:"total"`
List []GiftLog `json:"list"`
}
TrafficLogDetails {
Id int64 `json:"id"`
ServerId int64 `json:"server_id"`
UserId int64 `json:"user_id"`
SubscribeId int64 `json:"subscribe_id"`
Download int64 `json:"download"`
Upload int64 `json:"upload"`
Timestamp int64 `json:"timestamp"`
}
FilterTrafficLogDetailsRequest {
FilterLogParams
ServerId int64 `form:"server_id,optional"`
SubscribeId int64 `form:"subscribe_id,optional"`
UserId int64 `form:"user_id,optional"`
}
FilterTrafficLogDetailsResponse {
Total int64 `json:"total"`
List []TrafficLogDetails `json:"list"`
}
LogSetting {
AutoClear *bool `json:"auto_clear"`
ClearDays int64 `json:"clear_days"`
}
) )
@server ( @server (
@ -201,61 +36,5 @@ service ppanel {
@doc "Get message log list" @doc "Get message log list"
@handler GetMessageLogList @handler GetMessageLogList
get /message/list (GetMessageLogListRequest) returns (GetMessageLogListResponse) get /message/list (GetMessageLogListRequest) returns (GetMessageLogListResponse)
@doc "Filter email log"
@handler FilterEmailLog
get /email/list (FilterLogParams) returns (FilterEmailLogResponse)
@doc "Filter mobile log"
@handler FilterMobileLog
get /mobile/list (FilterLogParams) returns (FilterMobileLogResponse)
@doc "Filter subscribe log"
@handler FilterSubscribeLog
get /subscribe/list (FilterSubscribeLogRequest) returns (FilterSubscribeLogResponse)
@doc "Filter login log"
@handler FilterLoginLog
get /login/list (FilterLoginLogRequest) returns (FilterLoginLogResponse)
@doc "Filter register log"
@handler FilterRegisterLog
get /register/list (FilterRegisterLogRequest) returns (FilterRegisterLogResponse)
@doc "Filter reset subscribe log"
@handler FilterResetSubscribeLog
get /subscribe/reset/list (FilterResetSubscribeLogRequest) returns (FilterResetSubscribeLogResponse)
@doc "Filter user subscribe traffic log"
@handler FilterUserSubscribeTrafficLog
get /subscribe/traffic/list (FilterSubscribeTrafficRequest) returns (FilterSubscribeTrafficResponse)
@doc "Filter server traffic log"
@handler FilterServerTrafficLog
get /server/traffic/list (FilterServerTrafficLogRequest) returns (FilterServerTrafficLogResponse)
@doc "Filter balance log"
@handler FilterBalanceLog
get /balance/list (FilterBalanceLogRequest) returns (FilterBalanceLogResponse)
@doc "Filter commission log"
@handler FilterCommissionLog
get /commission/list (FilterCommissionLogRequest) returns (FilterCommissionLogResponse)
@doc "Filter gift log"
@handler FilterGiftLog
get /gift/list (FilterGiftLogRequest) returns (FilterGiftLogResponse)
@doc "Filter traffic log details"
@handler FilterTrafficLogDetails
get /traffic/details (FilterTrafficLogDetailsRequest) returns (FilterTrafficLogDetailsResponse)
@doc "Get log setting"
@handler GetLogSetting
get /setting returns (LogSetting)
@doc "Update log setting"
@handler UpdateLogSetting
post /setting (LogSetting)
} }

View File

@ -12,7 +12,7 @@ type (
CreateBatchSendEmailTaskRequest { CreateBatchSendEmailTaskRequest {
Subject string `json:"subject"` Subject string `json:"subject"`
Content string `json:"content"` Content string `json:"content"`
Scope int8 `json:"scope"` Scope string `json:"scope"`
RegisterStartTime int64 `json:"register_start_time,omitempty"` RegisterStartTime int64 `json:"register_start_time,omitempty"`
RegisterEndTime int64 `json:"register_end_time,omitempty"` RegisterEndTime int64 `json:"register_end_time,omitempty"`
Additional string `json:"additional,omitempty"` Additional string `json:"additional,omitempty"`
@ -25,7 +25,7 @@ type (
Subject string `json:"subject"` Subject string `json:"subject"`
Content string `json:"content"` Content string `json:"content"`
Recipients string `json:"recipients"` Recipients string `json:"recipients"`
Scope int8 `json:"scope"` Scope string `json:"scope"`
RegisterStartTime int64 `json:"register_start_time"` RegisterStartTime int64 `json:"register_start_time"`
RegisterEndTime int64 `json:"register_end_time"` RegisterEndTime int64 `json:"register_end_time"`
Additional string `json:"additional"` Additional string `json:"additional"`
@ -42,7 +42,7 @@ type (
GetBatchSendEmailTaskListRequest { GetBatchSendEmailTaskListRequest {
Page int `form:"page"` Page int `form:"page"`
Size int `form:"size"` Size int `form:"size"`
Scope *int8 `form:"scope,omitempty"` Scope string `form:"scope,omitempty"`
Status *uint8 `form:"status,omitempty"` Status *uint8 `form:"status,omitempty"`
} }
GetBatchSendEmailTaskListResponse { GetBatchSendEmailTaskListResponse {
@ -53,9 +53,9 @@ type (
Id int64 `json:"id"` Id int64 `json:"id"`
} }
GetPreSendEmailCountRequest { GetPreSendEmailCountRequest {
Scope int8 `json:"scope"` Scope string `json:"scope"`
RegisterStartTime int64 `json:"register_start_time,omitempty"` RegisterStartTime int64 `json:"register_start_time,omitempty"`
RegisterEndTime int64 `json:"register_end_time,omitempty"` RegisterEndTime int64 `json:"register_end_time,omitempty"`
} }
GetPreSendEmailCountResponse { GetPreSendEmailCountResponse {
Count int64 `json:"count"` Count int64 `json:"count"`
@ -69,61 +69,6 @@ type (
Total int64 `json:"total"` Total int64 `json:"total"`
Errors string `json:"errors"` Errors string `json:"errors"`
} }
CreateQuotaTaskRequest {
Subscribers []int64 `json:"subscribers"`
IsActive *bool `json:"is_active"`
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
ResetTraffic bool `json:"reset_traffic"`
Days uint64 `json:"days"`
GiftType uint8 `json:"gift_type"`
GiftValue uint64 `json:"gift_value"`
}
QuotaTask {
Id int64 `json:"id"`
Subscribers []int64 `json:"subscribers"`
IsActive *bool `json:"is_active"`
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
ResetTraffic bool `json:"reset_traffic"`
Days uint64 `json:"days"`
GiftType uint8 `json:"gift_type"`
GiftValue uint64 `json:"gift_value"`
Objects []int64 `json:"objects"` // UserSubscribe IDs
Status uint8 `json:"status"`
Total int64 `json:"total"`
Current int64 `json:"current"`
Errors string `json:"errors"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
QueryQuotaTaskPreCountRequest {
Subscribers []int64 `json:"subscribers"`
IsActive *bool `json:"is_active"`
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
}
QueryQuotaTaskPreCountResponse {
Count int64 `json:"count"`
}
QueryQuotaTaskListRequest {
Page int `form:"page"`
Size int `form:"size"`
Status *uint8 `form:"status,omitempty"`
}
QueryQuotaTaskListResponse {
Total int64 `json:"total"`
List []QuotaTask `json:"list"`
}
QueryQuotaTaskStatusRequest {
Id int64 `json:"id"`
}
QueryQuotaTaskStatusResponse {
Status uint8 `json:"status"`
Current int64 `json:"current"`
Total int64 `json:"total"`
Errors string `json:"errors"`
}
) )
@server ( @server (
@ -151,17 +96,5 @@ service ppanel {
@doc "Get batch send email task status" @doc "Get batch send email task status"
@handler GetBatchSendEmailTaskStatus @handler GetBatchSendEmailTaskStatus
post /email/batch/status (GetBatchSendEmailTaskStatusRequest) returns (GetBatchSendEmailTaskStatusResponse) post /email/batch/status (GetBatchSendEmailTaskStatusRequest) returns (GetBatchSendEmailTaskStatusResponse)
@doc "Create a quota task"
@handler CreateQuotaTask
post /quota/create (CreateQuotaTaskRequest)
@doc "Query quota task pre-count"
@handler QueryQuotaTaskPreCount
post /quota/pre-count (QueryQuotaTaskPreCountRequest) returns (QueryQuotaTaskPreCountResponse)
@doc "Query quota task list"
@handler QueryQuotaTaskList
get /quota/list (QueryQuotaTaskListRequest) returns (QueryQuotaTaskListResponse)
} }

View File

@ -11,137 +11,108 @@ info (
import "../types.api" import "../types.api"
type ( type (
ServerOnlineIP { GetNodeServerListRequest {
IP string `json:"ip"` Page int `form:"page" validate:"required"`
Protocol string `json:"protocol"` Size int `form:"size" validate:"required"`
Tags string `form:"tags,omitempty"`
GroupId int64 `form:"group_id,omitempty"`
Search string `form:"search,omitempty"`
} }
ServerOnlineUser { GetNodeServerListResponse {
IP []ServerOnlineIP `json:"ip"`
UserId int64 `json:"user_id"`
Subscribe string `json:"subscribe"`
SubscribeId int64 `json:"subscribe_id"`
Traffic int64 `json:"traffic"`
ExpiredAt int64 `json:"expired_at"`
}
ServerStatus {
Cpu float64 `json:"cpu"`
Mem float64 `json:"mem"`
Disk float64 `json:"disk"`
Protocol string `json:"protocol"`
Online []ServerOnlineUser `json:"online"`
Status string `json:"status"`
}
Server {
Id int64 `json:"id"`
Name string `json:"name"`
Country string `json:"country"`
City string `json:"city"`
Ratio float32 `json:"ratio"`
Address string `json:"address"`
Sort int `json:"sort"`
Protocols []Protocol `json:"protocols"`
LastReportedAt int64 `json:"last_reported_at"`
Status ServerStatus `json:"status"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
CreateServerRequest {
Name string `json:"name"`
Country string `json:"country,omitempty"`
City string `json:"city,omitempty"`
Ratio float32 `json:"ratio"`
Address string `json:"address"`
Sort int `json:"sort,omitempty"`
Protocols []Protocol `json:"protocols"`
}
UpdateServerRequest {
Id int64 `json:"id"`
Name string `json:"name"`
Country string `json:"country,omitempty"`
City string `json:"city,omitempty"`
Ratio float32 `json:"ratio"`
Address string `json:"address"`
Sort int `json:"sort,omitempty"`
Protocols []Protocol `json:"protocols"`
}
DeleteServerRequest {
Id int64 `json:"id"`
}
FilterServerListRequest {
Page int `form:"page"`
Size int `form:"size"`
Search string `form:"search,omitempty"`
}
FilterServerListResponse {
Total int64 `json:"total"` Total int64 `json:"total"`
List []Server `json:"list"` List []Server `json:"list"`
} }
GetServerProtocolsRequest { UpdateNodeRequest {
Id int64 `form:"id"` Id int64 `json:"id" validate:"required"`
} Tags []string `json:"tags"`
GetServerProtocolsResponse { Country string `json:"country"`
Protocols []Protocol `json:"protocols"` City string `json:"city"`
} Name string `json:"name" validate:"required"`
Node { ServerAddr string `json:"server_addr" validate:"required"`
Id int64 `json:"id"` RelayMode string `json:"relay_mode"`
Name string `json:"name"` RelayNode []NodeRelay `json:"relay_node"`
Tags []string `json:"tags"` SpeedLimit int `json:"speed_limit"`
Port uint16 `json:"port"` TrafficRatio float32 `json:"traffic_ratio"`
Address string `json:"address"` GroupId int64 `json:"group_id"`
ServerId int64 `json:"server_id"` Protocol string `json:"protocol" validate:"required"`
Protocol string `json:"protocol"` Config interface{} `json:"config" validate:"required"`
Enabled *bool `json:"enabled"` Enable *bool `json:"enable"`
Sort int `json:"sort,omitempty"` Sort int64 `json:"sort"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
} }
CreateNodeRequest { CreateNodeRequest {
Name string `json:"name"` Name string `json:"name" validate:"required"`
Tags []string `json:"tags,omitempty"` Tags []string `json:"tags"`
Port uint16 `json:"port"` Country string `json:"country"`
Address string `json:"address"` City string `json:"city"`
ServerId int64 `json:"server_id"` ServerAddr string `json:"server_addr" validate:"required"`
Protocol string `json:"protocol"` RelayMode string `json:"relay_mode"`
Enabled *bool `json:"enabled"` RelayNode []NodeRelay `json:"relay_node"`
} SpeedLimit int `json:"speed_limit"`
UpdateNodeRequest { TrafficRatio float32 `json:"traffic_ratio"`
Id int64 `json:"id"` GroupId int64 `json:"group_id"`
Name string `json:"name"` Protocol string `json:"protocol" validate:"required"`
Tags []string `json:"tags,omitempty"` Config interface{} `json:"config" validate:"required"`
Port uint16 `json:"port"` Enable *bool `json:"enable"`
Address string `json:"address"` Sort int64 `json:"sort"`
ServerId int64 `json:"server_id"`
Protocol string `json:"protocol"`
Enabled *bool `json:"enabled"`
}
ToggleNodeStatusRequest {
Id int64 `json:"id"`
Enable *bool `json:"enable"`
} }
DeleteNodeRequest { DeleteNodeRequest {
Id int64 `json:"id"` Id int64 `json:"id" validate:"required"`
} }
FilterNodeListRequest { GetNodeGroupListResponse {
Page int `form:"page"` Total int64 `json:"total"`
Size int `form:"size"` List []ServerGroup `json:"list"`
Search string `form:"search,omitempty"`
} }
FilterNodeListResponse { CreateNodeGroupRequest {
Total int64 `json:"total"` Name string `json:"name" validate:"required"`
List []Node `json:"list"` Description string `json:"description"`
} }
HasMigrateSeverNodeResponse { UpdateNodeGroupRequest {
HasMigrate bool `json:"has_migrate"` Id int64 `json:"id" validate:"required"`
Name string `json:"name" validate:"required"`
Description string `json:"description"`
} }
MigrateServerNodeResponse { DeleteNodeGroupRequest {
Succee uint64 `json:"succee"` Id int64 `json:"id" validate:"required"`
Fail uint64 `json:"fail"`
Message string `json:"message,omitempty"`
} }
ResetSortRequest { BatchDeleteNodeRequest {
Ids []int64 `json:"ids" validate:"required"`
}
BatchDeleteNodeGroupRequest {
Ids []int64 `json:"ids" validate:"required"`
}
GetNodeDetailRequest {
Id int64 `form:"id" validate:"required"`
}
NodeSortRequest {
Sort []SortItem `json:"sort"` Sort []SortItem `json:"sort"`
} }
QueryNodeTagResponse { CreateRuleGroupRequest {
Name string `json:"name" validate:"required"`
Icon string `json:"icon"`
Type string `json:"type"`
Tags []string `json:"tags"`
Rules string `json:"rules"`
Default bool `json:"default"`
Enable bool `json:"enable"`
}
UpdateRuleGroupRequest {
Id int64 `json:"id" validate:"required"`
Icon string `json:"icon"`
Type string `json:"type"`
Name string `json:"name" validate:"required"`
Tags []string `json:"tags"`
Rules string `json:"rules"`
Default bool `json:"default"`
Enable bool `json:"enable"`
}
DeleteRuleGroupRequest {
Id int64 `json:"id" validate:"required"`
}
GetRuleGroupResponse {
Total int64 `json:"total"`
List []ServerRuleGroup `json:"list"`
}
GetNodeTagListResponse {
Tags []string `json:"tags"` Tags []string `json:"tags"`
} }
) )
@ -152,64 +123,72 @@ type (
middleware: AuthMiddleware middleware: AuthMiddleware
) )
service ppanel { service ppanel {
@doc "Create Server" @doc "Get node tag list"
@handler CreateServer @handler GetNodeTagList
post /create (CreateServerRequest) get /tag/list returns (GetNodeTagListResponse)
@doc "Update Server" @doc "Get node list"
@handler UpdateServer @handler GetNodeList
post /update (UpdateServerRequest) get /list (GetNodeServerListRequest) returns (GetNodeServerListResponse)
@doc "Delete Server" @doc "Get node detail"
@handler DeleteServer @handler GetNodeDetail
post /delete (DeleteServerRequest) get /detail (GetNodeDetailRequest) returns (Server)
@doc "Filter Server List" @doc "Update node"
@handler FilterServerList
get /list (FilterServerListRequest) returns (FilterServerListResponse)
@doc "Get Server Protocols"
@handler GetServerProtocols
get /protocols (GetServerProtocolsRequest) returns (GetServerProtocolsResponse)
@doc "Create Node"
@handler CreateNode
post /node/create (CreateNodeRequest)
@doc "Update Node"
@handler UpdateNode @handler UpdateNode
post /node/update (UpdateNodeRequest) put / (UpdateNodeRequest)
@doc "Delete Node" @doc "Create node"
@handler CreateNode
post / (CreateNodeRequest)
@doc "Delete node"
@handler DeleteNode @handler DeleteNode
post /node/delete (DeleteNodeRequest) delete / (DeleteNodeRequest)
@doc "Filter Node List" @doc "Batch delete node"
@handler FilterNodeList @handler BatchDeleteNode
get /node/list (FilterNodeListRequest) returns (FilterNodeListResponse) delete /batch (BatchDeleteNodeRequest)
@doc "Toggle Node Status" @doc "Get node group list"
@handler ToggleNodeStatus @handler GetNodeGroupList
post /node/status/toggle (ToggleNodeStatusRequest) get /group/list returns (GetNodeGroupListResponse)
@doc "Check if there is any server or node to migrate" @doc "Create node group"
@handler HasMigrateSeverNode @handler CreateNodeGroup
get /migrate/has returns (HasMigrateSeverNodeResponse) post /group (CreateNodeGroupRequest)
@doc "Migrate server and node data to new database" @doc "Update node group"
@handler MigrateServerNode @handler UpdateNodeGroup
post /migrate/run returns (MigrateServerNodeResponse) put /group (UpdateNodeGroupRequest)
@doc "Reset server sort" @doc "Delete node group"
@handler ResetSortWithServer @handler DeleteNodeGroup
post /server/sort (ResetSortRequest) delete /group (DeleteNodeGroupRequest)
@doc "Reset node sort" @doc "Batch delete node group"
@handler ResetSortWithNode @handler BatchDeleteNodeGroup
post /node/sort (ResetSortRequest) delete /group/batch (BatchDeleteNodeGroupRequest)
@doc "Query all node tags" @doc "Node sort "
@handler QueryNodeTag @handler NodeSort
get /node/tags returns (QueryNodeTagResponse) post /sort (NodeSortRequest)
@doc "Create rule group"
@handler CreateRuleGroup
post /rule_group (CreateRuleGroupRequest)
@doc "Update rule group"
@handler UpdateRuleGroup
put /rule_group (UpdateRuleGroupRequest)
@doc "Delete rule group"
@handler DeleteRuleGroup
delete /rule_group (DeleteRuleGroupRequest)
@doc "Get rule group list"
@handler GetRuleGroupList
get /rule_group_list returns (GetRuleGroupResponse)
} }

View File

@ -35,7 +35,6 @@ type (
} }
CreateSubscribeRequest { CreateSubscribeRequest {
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Language string `json:"language"`
Description string `json:"description"` Description string `json:"description"`
UnitPrice int64 `json:"unit_price"` UnitPrice int64 `json:"unit_price"`
UnitTime string `json:"unit_time"` UnitTime string `json:"unit_time"`
@ -46,8 +45,9 @@ type (
SpeedLimit int64 `json:"speed_limit"` SpeedLimit int64 `json:"speed_limit"`
DeviceLimit int64 `json:"device_limit"` DeviceLimit int64 `json:"device_limit"`
Quota int64 `json:"quota"` Quota int64 `json:"quota"`
Nodes []int64 `json:"nodes"` GroupId int64 `json:"group_id"`
NodeTags []string `json:"node_tags"` ServerGroup []int64 `json:"server_group"`
Server []int64 `json:"server"`
Show *bool `json:"show"` Show *bool `json:"show"`
Sell *bool `json:"sell"` Sell *bool `json:"sell"`
DeductionRatio int64 `json:"deduction_ratio"` DeductionRatio int64 `json:"deduction_ratio"`
@ -58,7 +58,6 @@ type (
UpdateSubscribeRequest { UpdateSubscribeRequest {
Id int64 `json:"id" validate:"required"` Id int64 `json:"id" validate:"required"`
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Language string `json:"language"`
Description string `json:"description"` Description string `json:"description"`
UnitPrice int64 `json:"unit_price"` UnitPrice int64 `json:"unit_price"`
UnitTime string `json:"unit_time"` UnitTime string `json:"unit_time"`
@ -69,8 +68,9 @@ type (
SpeedLimit int64 `json:"speed_limit"` SpeedLimit int64 `json:"speed_limit"`
DeviceLimit int64 `json:"device_limit"` DeviceLimit int64 `json:"device_limit"`
Quota int64 `json:"quota"` Quota int64 `json:"quota"`
Nodes []int64 `json:"nodes"` GroupId int64 `json:"group_id"`
NodeTags []string `json:"node_tags"` ServerGroup []int64 `json:"server_group"`
Server []int64 `json:"server"`
Show *bool `json:"show"` Show *bool `json:"show"`
Sell *bool `json:"sell"` Sell *bool `json:"sell"`
Sort int64 `json:"sort"` Sort int64 `json:"sort"`
@ -83,10 +83,10 @@ type (
Sort []SortItem `json:"sort"` Sort []SortItem `json:"sort"`
} }
GetSubscribeListRequest { GetSubscribeListRequest {
Page int64 `form:"page" validate:"required"` Page int64 `form:"page" validate:"required"`
Size int64 `form:"size" validate:"required"` Size int64 `form:"size" validate:"required"`
Language string `form:"language,omitempty"` GroupId int64 `form:"group_id,omitempty"`
Search string `form:"search,omitempty"` Search string `form:"search,omitempty"`
} }
SubscribeItem { SubscribeItem {
Subscribe Subscribe

View File

@ -11,6 +11,50 @@ info (
import "../types.api" import "../types.api"
type ( type (
// Update application request
UpdateApplicationRequest {
Id int64 `json:"id" validate:"required"`
Icon string `json:"icon"`
Name string `json:"name"`
Description string `json:"description"`
SubscribeType string `json:"subscribe_type"`
Platform ApplicationPlatform `json:"platform"`
}
// Create application request
CreateApplicationRequest {
Icon string `json:"icon"`
Name string `json:"name"`
Description string `json:"description"`
SubscribeType string `json:"subscribe_type"`
Platform ApplicationPlatform `json:"platform"`
}
// Update application request
UpdateApplicationVersionRequest {
Id int64 `json:"id" validate:"required"`
Url string `json:"url"`
Version string `json:"version" validate:"required"`
Description string `json:"description"`
Platform string `json:"platform" validate:"required,oneof=windows mac linux android ios harmony"`
IsDefault bool `json:"is_default"`
ApplicationId int64 `json:"application_id" validate:"required"`
}
// Create application request
CreateApplicationVersionRequest {
Url string `json:"url"`
Version string `json:"version" validate:"required"`
Description string `json:"description"`
Platform string `json:"platform" validate:"required,oneof=windows mac linux android ios harmony"`
IsDefault bool `json:"is_default"`
ApplicationId int64 `json:"application_id" validate:"required"`
}
// Delete application request
DeleteApplicationRequest {
Id int64 `json:"id" validate:"required"`
}
// Delete application request
DeleteApplicationVersionRequest {
Id int64 `json:"id" validate:"required"`
}
GetNodeMultiplierResponse { GetNodeMultiplierResponse {
Periods []TimePeriod `json:"periods"` Periods []TimePeriod `json:"periods"`
} }
@ -42,6 +86,46 @@ service ppanel {
@handler UpdateSubscribeConfig @handler UpdateSubscribeConfig
put /subscribe_config (SubscribeConfig) put /subscribe_config (SubscribeConfig)
@doc "Get subscribe type"
@handler GetSubscribeType
get /subscribe_type returns (SubscribeType)
@doc "update application config"
@handler UpdateApplicationConfig
put /application_config (ApplicationConfig)
@doc "get application config"
@handler GetApplicationConfig
get /application_config returns (ApplicationConfig)
@doc "Get application"
@handler GetApplication
get /application returns (ApplicationResponse)
@doc "Update application"
@handler UpdateApplication
put /application (UpdateApplicationRequest)
@doc "Create application"
@handler CreateApplication
post /application (CreateApplicationRequest)
@doc "Delete application"
@handler DeleteApplication
delete /application (DeleteApplicationRequest)
@doc "Update application version"
@handler UpdateApplicationVersion
put /application_version (UpdateApplicationVersionRequest)
@doc "Create application version"
@handler CreateApplicationVersion
post /application_version (CreateApplicationVersionRequest)
@doc "Delete application"
@handler DeleteApplicationVersion
delete /application_version (DeleteApplicationVersionRequest)
@doc "Get register config" @doc "Get register config"
@handler GetRegisterConfig @handler GetRegisterConfig
get /register_config returns (RegisterConfig) get /register_config returns (RegisterConfig)

View File

@ -32,19 +32,17 @@ type (
Id int64 `form:"id" validate:"required"` Id int64 `form:"id" validate:"required"`
} }
UpdateUserBasiceInfoRequest { UpdateUserBasiceInfoRequest {
UserId int64 `json:"user_id" validate:"required"` UserId int64 `json:"user_id" validate:"required"`
Password string `json:"password"` Password string `json:"password"`
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Balance int64 `json:"balance"` Balance int64 `json:"balance"`
Commission int64 `json:"commission"` Commission int64 `json:"commission"`
ReferralPercentage uint8 `json:"referral_percentage"` GiftAmount int64 `json:"gift_amount"`
OnlyFirstPurchase bool `json:"only_first_purchase"` Telegram int64 `json:"telegram"`
GiftAmount int64 `json:"gift_amount"` ReferCode string `json:"refer_code"`
Telegram int64 `json:"telegram"` RefererId int64 `json:"referer_id"`
ReferCode string `json:"refer_code"` Enable bool `json:"enable"`
RefererId int64 `json:"referer_id"` IsAdmin bool `json:"is_admin"`
Enable bool `json:"enable"`
IsAdmin bool `json:"is_admin"`
} }
UpdateUserNotifySettingRequest { UpdateUserNotifySettingRequest {
UserId int64 `json:"user_id" validate:"required"` UserId int64 `json:"user_id" validate:"required"`
@ -54,20 +52,18 @@ type (
EnableTradeNotify bool `json:"enable_trade_notify"` EnableTradeNotify bool `json:"enable_trade_notify"`
} }
CreateUserRequest { CreateUserRequest {
Email string `json:"email"` Email string `json:"email"`
Telephone string `json:"telephone"` Telephone string `json:"telephone"`
TelephoneAreaCode string `json:"telephone_area_code"` TelephoneAreaCode string `json:"telephone_area_code"`
Password string `json:"password"` Password string `json:"password"`
ProductId int64 `json:"product_id"` ProductId int64 `json:"product_id"`
Duration int64 `json:"duration"` Duration int64 `json:"duration"`
ReferralPercentage uint8 `json:"referral_percentage"` RefererUser string `json:"referer_user"`
OnlyFirstPurchase bool `json:"only_first_purchase"` ReferCode string `json:"refer_code"`
RefererUser string `json:"referer_user"` Balance int64 `json:"balance"`
ReferCode string `json:"refer_code"` Commission int64 `json:"commission"`
Balance int64 `json:"balance"` GiftAmount int64 `json:"gift_amount"`
Commission int64 `json:"commission"` IsAdmin bool `json:"is_admin"`
GiftAmount int64 `json:"gift_amount"`
IsAdmin bool `json:"is_admin"`
} }
UserSubscribeDetail { UserSubscribeDetail {
Id int64 `json:"id"` Id int64 `json:"id"`
@ -168,15 +164,6 @@ type (
List []UserLoginLog `json:"list"` List []UserLoginLog `json:"list"`
Total int64 `json:"total"` Total int64 `json:"total"`
} }
GetUserSubscribeResetTrafficLogsRequest {
Page int `form:"page"`
Size int `form:"size"`
UserSubscribeId int64 `form:"user_subscribe_id"`
}
GetUserSubscribeResetTrafficLogsResponse {
List []ResetSubscribeTrafficLog `json:"list"`
Total int64 `json:"total"`
}
DeleteUserSubscribeRequest { DeleteUserSubscribeRequest {
UserSubscribeId int64 `json:"user_subscribe_id"` UserSubscribeId int64 `json:"user_subscribe_id"`
} }
@ -264,10 +251,6 @@ service ppanel {
@handler GetUserSubscribeLogs @handler GetUserSubscribeLogs
get /subscribe/logs (GetUserSubscribeLogsRequest) returns (GetUserSubscribeLogsResponse) get /subscribe/logs (GetUserSubscribeLogsRequest) returns (GetUserSubscribeLogsResponse)
@doc "Get user subcribe reset traffic logs"
@handler GetUserSubscribeResetTrafficLogs
get /subscribe/reset/logs (GetUserSubscribeResetTrafficLogsRequest) returns (GetUserSubscribeResetTrafficLogsResponse)
@doc "Get user subcribe traffic logs" @doc "Get user subcribe traffic logs"
@handler GetUserSubscribeTrafficLogs @handler GetUserSubscribeTrafficLogs
get /subscribe/traffic_logs (GetUserSubscribeTrafficLogsRequest) returns (GetUserSubscribeTrafficLogsResponse) get /subscribe/traffic_logs (GetUserSubscribeTrafficLogsRequest) returns (GetUserSubscribeTrafficLogsResponse)

23
apis/app/announcement.api Normal file
View File

@ -0,0 +1,23 @@
syntax = "v1"
info (
title: "Announcement API"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import "../types.api"
@server (
prefix: v1/app/announcement
group: app/announcement
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "Query announcement"
@handler QueryAnnouncement
get /list (QueryAnnouncementRequest) returns (QueryAnnouncementResponse)
}

104
apis/app/auth.api Normal file
View File

@ -0,0 +1,104 @@
syntax = "v1"
info (
title: "App Auth Api"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import (
"../types.api"
)
type (
AppAuthCheckRequest {
Method string `json:"method" validate:"required" validate:"required,oneof=device email mobile"`
Account string `json:"account"`
Identifier string `json:"identifier" validate:"required"`
UserAgent string `json:"user_agent" validate:"required,oneof=windows mac linux android ios harmony"`
AreaCode string `json:"area_code"`
}
AppAuthCheckResponse {
Status bool
}
AppAuthRequest {
Method string `json:"method" validate:"required" validate:"required,oneof=device email mobile"`
Account string `json:"account"`
Password string `json:"password"`
Identifier string `json:"identifier" validate:"required"`
UserAgent string `json:"user_agent" validate:"required,oneof=windows mac linux android ios harmony"`
Code string `json:"code"`
Invite string `json:"invite"`
AreaCode string `json:"area_code"`
CfToken string `json:"cf_token,optional"`
}
AppAuthRespone {
Token string `json:"token"`
}
AppSendCodeRequest {
Method string `json:"method" validate:"required" validate:"required,oneof=email mobile"`
Account string `json:"account"`
AreaCode string `json:"area_code"`
CfToken string `json:"cf_token,optional"`
}
AppSendCodeRespone {
Status bool `json:"status"`
Code string `json:"code,omitempty"`
}
AppConfigRequest {
UserAgent string `json:"user_agent" validate:"required,oneof=windows mac linux android ios harmony"`
}
AppConfigResponse {
EncryptionKey string `json:"encryption_key"`
EncryptionMethod string `json:"encryption_method"`
Domains []string `json:"domains"`
StartupPicture string `json:"startup_picture"`
StartupPictureSkipTime int64 `json:"startup_picture_skip_time"`
Application AppInfo `json:"applications"`
OfficialEmail string `json:"official_email"`
OfficialWebsite string `json:"official_website"`
OfficialTelegram string `json:"official_telegram"`
OfficialTelephone string `json:"official_telephone"`
InvitationLink string `json:"invitation_link"`
KrWebsiteId string `json:"kr_website_id"`
}
AppInfo {
Id int64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Url string `json:"url"`
Version string `json:"version"`
VersionDescription string `json:"version_description"`
IsDefault bool `json:"is_default"`
}
)
@server (
prefix: v1/app/auth
group: app/auth
middleware: AppMiddleware
)
service ppanel {
@doc "Check Account"
@handler Check
post /check (AppAuthCheckRequest) returns (AppAuthCheckResponse)
@doc "Login"
@handler Login
post /login (AppAuthRequest) returns (AppAuthRespone)
@doc "Register"
@handler Register
post /register (AppAuthRequest) returns (AppAuthRespone)
@doc "Reset Password"
@handler ResetPassword
post /reset_password (AppAuthRequest) returns (AppAuthRespone)
@doc "GetAppConfig"
@handler GetAppConfig
post /config (AppConfigRequest) returns (AppConfigResponse)
}

27
apis/app/document.api Normal file
View File

@ -0,0 +1,27 @@
syntax = "v1"
info (
title: "Document API"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import "../types.api"
@server (
prefix: v1/app/document
group: app/document
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "Get document list"
@handler QueryDocumentList
get /list returns (QueryDocumentListResponse)
@doc "Get document detail"
@handler QueryDocumentDetail
get /detail (QueryDocumentDetailRequest) returns (Document)
}

40
apis/app/node.api Normal file
View File

@ -0,0 +1,40 @@
syntax = "v1"
info (
title: "App Node Api"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import "../types.api"
type (
AppRuleGroupListResponse {
Total int64 `json:"total"`
List []ServerRuleGroup `json:"list"`
}
AppUserSubscbribeNodeRequest {
Id int64 `form:"id" validate:"required"`
}
AppUserSubscbribeNodeResponse {
List []AppUserSubscbribeNode `json:"list"`
}
)
@server (
prefix: v1/app/node
group: app/node
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "Get Node list"
@handler GetNodeList
get /list (AppUserSubscbribeNodeRequest) returns (AppUserSubscbribeNodeResponse)
@doc "Get rule group list"
@handler GetRuleGroupList
get /rule_group_list returns (AppRuleGroupListResponse)
}

57
apis/app/order.api Normal file
View File

@ -0,0 +1,57 @@
syntax = "v1"
info (
title: "Order API"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import (
"../types.api"
)
@server (
prefix: v1/app/order
group: app/order
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "Pre create order"
@handler PreCreateOrder
post /pre (PurchaseOrderRequest) returns (PreOrderResponse)
@doc "purchase Subscription"
@handler Purchase
post /purchase (PurchaseOrderRequest) returns (PurchaseOrderResponse)
@doc "Renewal Subscription"
@handler Renewal
post /renewal (RenewalOrderRequest) returns (RenewalOrderResponse)
@doc "Reset traffic"
@handler ResetTraffic
post /reset (ResetTrafficOrderRequest) returns (ResetTrafficOrderResponse)
@doc "Recharge"
@handler Recharge
post /recharge (RechargeOrderRequest) returns (RechargeOrderResponse)
@doc "Checkout order"
@handler CheckoutOrder
post /checkout (CheckoutOrderRequest) returns (CheckoutOrderResponse)
@doc "Close order"
@handler CloseOrder
post /close (CloseOrderRequest)
@doc "Get order"
@handler QueryOrderDetail
get /detail (QueryOrderDetailRequest) returns (OrderDetail)
@doc "Get order list"
@handler QueryOrderList
get /list (QueryOrderListRequest) returns (QueryOrderListResponse)
}

23
apis/app/payment.api Normal file
View File

@ -0,0 +1,23 @@
syntax = "v1"
info (
title: "payment API"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import "../types.api"
@server (
prefix: v1/app/payment
group: app/payment
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "Get available payment methods"
@handler GetAvailablePaymentMethods
get /methods returns (GetAvailablePaymentMethodsResponse)
}

65
apis/app/subscribe.api Normal file
View File

@ -0,0 +1,65 @@
syntax = "v1"
info (
title: "Subscribe API"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import "../types.api"
type (
QueryUserSubscribeResp {
Data []UserSubscribeData `json:"data"`
}
UserSubscribeData {
SubscribeId int64 `json:"subscribe_id"`
UserSubscribeId int64 `json:"user_subscribe_id"`
}
UserSubscribeResetPeriodRequest {
UserSubscribeId int64 `json:"user_subscribe_id"`
}
UserSubscribeResetPeriodResponse {
Status bool `json:"status"`
}
AppUserSubscribeRequest {
ContainsNodes *bool `form:"contains_nodes"`
}
AppUserSubscbribeResponse {
List []AppUserSubcbribe `json:"list"`
}
)
@server (
prefix: v1/app/subscribe
group: app/subscribe
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "Get subscribe list"
@handler QuerySubscribeList
get /list returns (QuerySubscribeListResponse)
@doc "Get subscribe group list"
@handler QuerySubscribeGroupList
get /group/list returns (QuerySubscribeGroupListResponse)
@doc "Get application config"
@handler QueryApplicationConfig
get /application/config returns (ApplicationResponse)
@doc "Get Already subscribed to package"
@handler QueryUserAlreadySubscribe
get /user/already_subscribe returns (QueryUserSubscribeResp)
@doc "Get Available subscriptions for users"
@handler QueryUserAvailableUserSubscribe
get /user/available_subscribe (AppUserSubscribeRequest) returns (AppUserSubscbribeResponse)
@doc "Reset user subscription period"
@handler ResetUserSubscribePeriod
post /reset/period (UserSubscribeResetPeriodRequest) returns (UserSubscribeResetPeriodResponse)
}

86
apis/app/user.api Normal file
View File

@ -0,0 +1,86 @@
syntax = "v1"
info (
title: "App User Api"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import (
"../types.api"
)
type (
UserInfoResponse {
Id int64 `json:"id"`
Balance int64 `json:"balance"`
Email string `json:"email"`
RefererId int64 `json:"referer_id"`
ReferCode string `json:"refer_code"`
Avatar string `json:"avatar"`
AreaCode string `json:"area_code"`
Telephone string `json:"telephone"`
Devices []UserDevice `json:"devices"`
AuthMethods []UserAuthMethod `json:"auth_methods"`
}
UpdatePasswordRequeset {
Password string `json:"password"`
NewPassword string `json:"new_password"`
}
DeleteAccountRequest {
Method string `json:"method" validate:"required" validate:"required,oneof=email telephone device"`
Code string `json:"code"`
}
GetUserOnlineTimeStatisticsResponse {
WeeklyStats []WeeklyStat `json:"weekly_stats"`
ConnectionRecords ConnectionRecords `json:"connection_records"`
}
WeeklyStat {
Day int `json:"day"`
DayName string `json:"day_name"`
Hours float64 `json:"hours"`
}
ConnectionRecords {
CurrentContinuousDays int64 `json:"current_continuous_days"`
HistoryContinuousDays int64 `json:"history_continuous_days"`
LongestSingleConnection int64 `json:"longest_single_connection"`
}
)
@server (
prefix: v1/app/user
group: app/user
middleware: AppMiddleware,AuthMiddleware
)
service ppanel {
@doc "query user info"
@handler QueryUserInfo
get /info returns (UserInfoResponse)
@doc "Update Password "
@handler UpdatePassword
put /password (UpdatePasswordRequeset)
@doc "Delete Account"
@handler DeleteAccount
delete /account (DeleteAccountRequest)
@doc "Get user subcribe traffic logs"
@handler GetUserSubscribeTrafficLogs
get /subscribe/traffic_logs (GetUserSubscribeTrafficLogsRequest) returns (GetUserSubscribeTrafficLogsResponse)
@doc "Get user online time total"
@handler GetUserOnlineTimeStatistics
get /online_time/statistics returns (GetUserOnlineTimeStatisticsResponse)
@doc "Query User Affiliate List"
@handler QueryUserAffiliateList
get /affiliate/list (QueryUserAffiliateListRequest) returns (QueryUserAffiliateListResponse)
@doc "Query User Affiliate Count"
@handler QueryUserAffiliate
get /affiliate/count returns (QueryUserAffiliateCountResponse)
}

21
apis/app/ws.api Normal file
View File

@ -0,0 +1,21 @@
syntax = "v1"
info (
title: "App Heartbeat Api"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
@server (
prefix: v1/app/ws
group: app/ws
middleware: AuthMiddleware
)
service ppanel {
@doc "App heartbeat"
@handler AppWs
get /:userid/:identifier
}

View File

@ -65,7 +65,6 @@ type (
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"` TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
Password string `json:"password"` Password string `json:"password"`
IP string `header:"X-Original-Forwarded-For"` IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
CfToken string `json:"cf_token,optional"` CfToken string `json:"cf_token,optional"`
} }
// Check user is exist request // Check user is exist request
@ -85,7 +84,6 @@ type (
Invite string `json:"invite,optional"` Invite string `json:"invite,optional"`
Code string `json:"code,optional"` Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"` IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
CfToken string `json:"cf_token,optional"` CfToken string `json:"cf_token,optional"`
} }
// User login response // User login response
@ -95,7 +93,6 @@ type (
Password string `json:"password" validate:"required"` Password string `json:"password" validate:"required"`
Code string `json:"code,optional"` Code string `json:"code,optional"`
IP string `header:"X-Original-Forwarded-For"` IP string `header:"X-Original-Forwarded-For"`
UserAgent string `header:"User-Agent"`
CfToken string `json:"cf_token,optional"` CfToken string `json:"cf_token,optional"`
} }
AppleLoginCallbackRequest { AppleLoginCallbackRequest {

View File

@ -35,6 +35,10 @@ type (
GetTosResponse { GetTosResponse {
TosContent string `json:"tos_content"` TosContent string `json:"tos_content"`
} }
GetAppcationResponse {
Config ApplicationConfig `json:"config"`
Applications []ApplicationResponseInfo `json:"applications"`
}
// GetCodeRequest Get code request // GetCodeRequest Get code request
SendCodeRequest { SendCodeRequest {
Email string `json:"email" validate:"required"` Email string `json:"email" validate:"required"`
@ -98,6 +102,10 @@ service ppanel {
@handler GetGlobalConfig @handler GetGlobalConfig
get /site/config returns (GetGlobalConfigResponse) get /site/config returns (GetGlobalConfigResponse)
@doc "Get Tos Content"
@handler GetApplication
get /application returns (GetAppcationResponse)
@doc "Get Tos Content" @doc "Get Tos Content"
@handler GetTos @handler GetTos
get /site/tos returns (GetTosResponse) get /site/tos returns (GetTosResponse)

View File

@ -11,10 +11,6 @@ info (
import "../types.api" import "../types.api"
type ( type (
OnlineUser {
SID int64 `json:"uid"`
IP string `json:"ip"`
}
ShadowsocksProtocol { ShadowsocksProtocol {
Port int `json:"port"` Port int `json:"port"`
Method string `json:"method"` Method string `json:"method"`
@ -93,13 +89,6 @@ type (
ServerCommon ServerCommon
Users []OnlineUser `json:"users"` Users []OnlineUser `json:"users"`
} }
QueryServerConfigRequest {
ServerID int64 `path:"server_id"`
SecretKey string `header:"secret_key"`
}
QueryServerConfigResponse {
Protocols []Protocol `json:"protocols"`
}
) )
@server ( @server (
@ -129,13 +118,3 @@ service ppanel {
post /online (OnlineUsersRequest) post /online (OnlineUsersRequest)
} }
@server (
prefix: v2/server
group: server
)
service ppanel {
@doc "Get Server Protocol Config"
@handler QueryServerProtocolConfig
get /:server_id (QueryServerConfigRequest) returns (QueryServerConfigResponse)
}

View File

@ -25,9 +25,6 @@ type (
PortalPurchaseResponse { PortalPurchaseResponse {
OrderNo string `json:"order_no"` OrderNo string `json:"order_no"`
} }
GetSubscriptionRequest {
Language string `form:"language"`
}
GetSubscriptionResponse { GetSubscriptionResponse {
List []Subscribe `json:"list"` List []Subscribe `json:"list"`
} }
@ -78,7 +75,7 @@ service ppanel {
@doc "Get Subscription" @doc "Get Subscription"
@handler GetSubscription @handler GetSubscription
get /subscribe (GetSubscriptionRequest) returns (GetSubscriptionResponse) get /subscribe returns (GetSubscriptionResponse)
@doc "Pre Purchase Order" @doc "Pre Purchase Order"
@handler PrePurchaseOrder @handler PrePurchaseOrder

View File

@ -10,12 +10,6 @@ info (
import "../types.api" import "../types.api"
type (
QuerySubscribeListRequest {
Language string `form:"language"`
}
)
@server ( @server (
prefix: v1/public/subscribe prefix: v1/public/subscribe
group: public/subscribe group: public/subscribe
@ -24,6 +18,14 @@ type (
service ppanel { service ppanel {
@doc "Get subscribe list" @doc "Get subscribe list"
@handler QuerySubscribeList @handler QuerySubscribeList
get /list (QuerySubscribeListRequest) returns (QuerySubscribeListResponse) get /list returns (QuerySubscribeListResponse)
@doc "Get subscribe group list"
@handler QuerySubscribeGroupList
get /group/list returns (QuerySubscribeGroupListResponse)
@doc "Get application config"
@handler QueryApplicationConfig
get /application/config returns (ApplicationResponse)
} }

View File

@ -25,8 +25,15 @@ type (
Total int64 `json:"total"` Total int64 `json:"total"`
} }
QueryUserBalanceLogListResponse { QueryUserBalanceLogListResponse {
List []BalanceLog `json:"list"` List []UserBalanceLog `json:"list"`
Total int64 `json:"total"` Total int64 `json:"total"`
}
CommissionLog {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
OrderNo string `json:"order_no"`
Amount int64 `json:"amount"`
CreatedAt int64 `json:"created_at"`
} }
QueryUserCommissionLogListRequest { QueryUserCommissionLogListRequest {
Page int `form:"page"` Page int `form:"page"`

22
apis/swagger_app.api Normal file
View File

@ -0,0 +1,22 @@
syntax = "v1"
info (
title: "App API"
desc: "API for ppanel"
author: "Tension"
email: "tension@ppanel.com"
version: "0.0.1"
)
import (
"./app/auth.api"
"./app/user.api"
"./app/node.api"
"./app/ws.api"
"./app/order.api"
"./app/announcement.api"
"./app/payment.api"
"./app/document.api"
"./app/subscribe.api"
)

View File

@ -14,8 +14,6 @@ type (
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Balance int64 `json:"balance"` Balance int64 `json:"balance"`
Commission int64 `json:"commission"` Commission int64 `json:"commission"`
ReferralPercentage uint8 `json:"referral_percentage"`
OnlyFirstPurchase bool `json:"only_first_purchase"`
GiftAmount int64 `json:"gift_amount"` GiftAmount int64 `json:"gift_amount"`
Telegram int64 `json:"telegram"` Telegram int64 `json:"telegram"`
ReferCode string `json:"refer_code"` ReferCode string `json:"refer_code"`
@ -185,7 +183,6 @@ type (
Subscribe { Subscribe {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Language string `json:"language"`
Description string `json:"description"` Description string `json:"description"`
UnitPrice int64 `json:"unit_price"` UnitPrice int64 `json:"unit_price"`
UnitTime string `json:"unit_time"` UnitTime string `json:"unit_time"`
@ -196,8 +193,9 @@ type (
SpeedLimit int64 `json:"speed_limit"` SpeedLimit int64 `json:"speed_limit"`
DeviceLimit int64 `json:"device_limit"` DeviceLimit int64 `json:"device_limit"`
Quota int64 `json:"quota"` Quota int64 `json:"quota"`
Nodes []int64 `json:"nodes"` GroupId int64 `json:"group_id"`
NodeTags []string `json:"node_tags"` ServerGroup []int64 `json:"server_group"`
Server []int64 `json:"server"`
Show bool `json:"show"` Show bool `json:"show"`
Sell bool `json:"sell"` Sell bool `json:"sell"`
Sort int64 `json:"sort"` Sort int64 `json:"sort"`
@ -276,37 +274,37 @@ type (
Host string `json:"host"` Host string `json:"host"`
ServiceName string `json:"service_name"` ServiceName string `json:"service_name"`
} }
// Server { Server {
// Id int64 `json:"id"` Id int64 `json:"id"`
// Tags []string `json:"tags"` Tags []string `json:"tags"`
// Country string `json:"country"` Country string `json:"country"`
// City string `json:"city"` City string `json:"city"`
// Name string `json:"name"` Name string `json:"name"`
// ServerAddr string `json:"server_addr"` ServerAddr string `json:"server_addr"`
// RelayMode string `json:"relay_mode"` RelayMode string `json:"relay_mode"`
// RelayNode []NodeRelay `json:"relay_node"` RelayNode []NodeRelay `json:"relay_node"`
// SpeedLimit int `json:"speed_limit"` SpeedLimit int `json:"speed_limit"`
// TrafficRatio float32 `json:"traffic_ratio"` TrafficRatio float32 `json:"traffic_ratio"`
// GroupId int64 `json:"group_id"` GroupId int64 `json:"group_id"`
// Protocol string `json:"protocol"` Protocol string `json:"protocol"`
// Config interface{} `json:"config"` Config interface{} `json:"config"`
// Enable *bool `json:"enable"` Enable *bool `json:"enable"`
// CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
// UpdatedAt int64 `json:"updated_at"` UpdatedAt int64 `json:"updated_at"`
// Status *NodeStatus `json:"status"` Status *NodeStatus `json:"status"`
// Sort int64 `json:"sort"` Sort int64 `json:"sort"`
// } }
// OnlineUser { OnlineUser {
// SID int64 `json:"uid"` SID int64 `json:"uid"`
// IP string `json:"ip"` IP string `json:"ip"`
// } }
// NodeStatus { NodeStatus {
// Online interface{} `json:"online"` Online interface{} `json:"online"`
// Cpu float64 `json:"cpu"` Cpu float64 `json:"cpu"`
// Mem float64 `json:"mem"` Mem float64 `json:"mem"`
// Disk float64 `json:"disk"` Disk float64 `json:"disk"`
// UpdatedAt int64 `json:"updated_at"` UpdatedAt int64 `json:"updated_at"`
// } }
ServerGroup { ServerGroup {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
@ -448,6 +446,15 @@ type (
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"` UpdatedAt int64 `json:"updated_at"`
} }
UserBalanceLog {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"`
Type uint8 `json:"type"`
OrderId int64 `json:"order_id"`
Balance int64 `json:"balance"`
CreatedAt int64 `json:"created_at"`
}
UserAffiliate { UserAffiliate {
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
Identifier string `json:"identifier"` Identifier string `json:"identifier"`
@ -468,6 +475,14 @@ type (
Port int `json:"port"` Port int `json:"port"`
Prefix string `json:"prefix"` Prefix string `json:"prefix"`
} }
ApplicationConfig {
AppId int64 `json:"app_id"`
EncryptionKey string `json:"encryption_key"`
EncryptionMethod string `json:"encryption_method"`
Domains []string `json:"domains" validate:"required"`
StartupPicture string `json:"startup_picture"`
StartupPictureSkipTime int64 `json:"startup_picture_skip_time"`
}
UserDevice { UserDevice {
Id int64 `json:"id"` Id int64 `json:"id"`
Ip string `json:"ip"` Ip string `json:"ip"`
@ -517,7 +532,7 @@ type (
Token string `json:"token"` Token string `json:"token"`
IP string `json:"ip"` IP string `json:"ip"`
UserAgent string `json:"user_agent"` UserAgent string `json:"user_agent"`
Timestamp int64 `json:"timestamp"` CreatedAt int64 `json:"created_at"`
} }
UserLoginLog { UserLoginLog {
Id int64 `json:"id"` Id int64 `json:"id"`
@ -525,17 +540,18 @@ type (
LoginIP string `json:"login_ip"` LoginIP string `json:"login_ip"`
UserAgent string `json:"user_agent"` UserAgent string `json:"user_agent"`
Success bool `json:"success"` Success bool `json:"success"`
Timestamp int64 `json:"timestamp"` CreatedAt int64 `json:"created_at"`
} }
MessageLog { MessageLog {
Id int64 `json:"id"` Id int64 `json:"id"`
Type uint8 `json:"type"` Type string `json:"type"`
Platform string `json:"platform"` Platform string `json:"platform"`
To string `json:"to"` To string `json:"to"`
Subject string `json:"subject"` Subject string `json:"subject"`
Content interface{} `json:"content"` Content string `json:"content"`
Status uint8 `json:"status"` Status int `json:"status"`
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
} }
Ads { Ads {
Id int `json:"id"` Id int `json:"id"`
@ -747,72 +763,5 @@ type (
Linux string `json:"linux,omitempty"` Linux string `json:"linux,omitempty"`
Harmony string `json:"harmony,omitempty"` Harmony string `json:"harmony,omitempty"`
} }
ResetSubscribeTrafficLog {
Id int64 `json:"id"`
Type uint16 `json:"type"`
UserSubscribeId int64 `json:"user_subscribe_id"`
OrderNo string `json:"order_no,omitempty"`
Timestamp int64 `json:"timestamp"`
}
BalanceLog {
Type uint16 `json:"type"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"`
OrderNo string `json:"order_no,omitempty"`
Balance int64 `json:"balance"`
Timestamp int64 `json:"timestamp"`
}
CommissionLog {
Type uint16 `json:"type"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"`
OrderNo string `json:"order_no"`
Timestamp int64 `json:"timestamp"`
}
Protocol {
Type string `json:"type"`
Port uint16 `json:"port"`
Enable bool `json:"enable"`
Security string `json:"security,omitempty"`
SNI string `json:"sni,omitempty"`
AllowInsecure bool `json:"allow_insecure,omitempty"`
Fingerprint string `json:"fingerprint,omitempty"`
RealityServerAddr string `json:"reality_server_addr,omitempty"`
RealityServerPort int `json:"reality_server_port,omitempty"`
RealityPrivateKey string `json:"reality_private_key,omitempty"`
RealityPublicKey string `json:"reality_public_key,omitempty"`
RealityShortId string `json:"reality_short_id,omitempty"`
Transport string `json:"transport,omitempty"`
Host string `json:"host,omitempty"`
Path string `json:"path,omitempty"`
ServiceName string `json:"service_name,omitempty"`
Cipher string `json:"cipher,omitempty"`
ServerKey string `json:"server_key,omitempty"`
Flow string `json:"flow,omitempty"`
HopPorts string `json:"hop_ports,omitempty"`
HopInterval int `json:"hop_interval,omitempty"`
ObfsPassword string `json:"obfs_password,omitempty"`
DisableSNI bool `json:"disable_sni,omitempty"`
ReduceRtt bool `json:"reduce_rtt,omitempty"`
UDPRelayMode string `json:"udp_relay_mode,omitempty"`
CongestionController string `json:"congestion_controller,omitempty"`
Multiplex string `json:"multiplex,omitempty"` // mux, eg: off/low/medium/high
PaddingScheme string `json:"padding_scheme,omitempty"` // padding scheme
UpMbps int `json:"up_mbps,omitempty"` // upload speed limit
DownMbps int `json:"down_mbps,omitempty"` // download speed limit
Obfs string `json:"obfs,omitempty"` // obfs, 'none', 'http', 'tls'
ObfsHost string `json:"obfs_host,omitempty"` // obfs host
ObfsPath string `json:"obfs_path,omitempty"` // obfs path
XhttpMode string `json:"xhttp_mode,omitempty"` // xhttp mode
XhttpExtra string `json:"xhttp_extra,omitempty"` // xhttp extra path
Encryption string `json:"encryption,omitempty"` // encryption'none', 'mlkem768x25519plus'
EncryptionMode string `json:"encryption_mode,omitempty"` // encryption mode'native', 'xorpub', 'random'
EncryptionRtt string `json:"encryption_rtt,omitempty"` // encryption rtt'0rtt', '1rtt'
EncryptionTicket string `json:"encryption_ticket,omitempty"` // encryption ticket
EncryptionServerPadding string `json:"encryption_server_padding,omitempty"` // encryption server padding
EncryptionPrivateKey string `json:"encryption_private_key,omitempty"` // encryption private key
EncryptionClientPadding string `json:"encryption_client_padding,omitempty"` // encryption client padding
EncryptionPassword string `json:"encryption_password,omitempty"` // encryption password
}
) )

4
go.mod
View File

@ -20,7 +20,7 @@ require (
github.com/go-sql-driver/mysql v1.8.1 github.com/go-sql-driver/mysql v1.8.1
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/gofrs/uuid/v5 v5.3.0 github.com/gofrs/uuid/v5 v5.3.0
github.com/golang-jwt/jwt/v5 v5.2.2 github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
github.com/hibiken/asynq v0.24.1 github.com/hibiken/asynq v0.24.1
@ -28,7 +28,7 @@ require (
github.com/klauspost/compress v1.17.7 github.com/klauspost/compress v1.17.7
github.com/nyaruka/phonenumbers v1.5.0 github.com/nyaruka/phonenumbers v1.5.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/redis/go-redis/v9 v9.7.2 github.com/redis/go-redis/v9 v9.6.1
github.com/smartwalle/alipay/v3 v3.2.23 github.com/smartwalle/alipay/v3 v3.2.23
github.com/spf13/cast v1.7.0 // indirect github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1

8
go.sum
View File

@ -155,8 +155,8 @@ github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-migrate/migrate/v4 v4.18.2 h1:2VSCMz7x7mjyTXx3m2zPokOY82LTRgxK1yQYKo6wWQ8= github.com/golang-migrate/migrate/v4 v4.18.2 h1:2VSCMz7x7mjyTXx3m2zPokOY82LTRgxK1yQYKo6wWQ8=
github.com/golang-migrate/migrate/v4 v4.18.2/go.mod h1:2CM6tJvn2kqPXwnXO/d3rAQYiyoIm180VsO8PRX6Rpk= github.com/golang-migrate/migrate/v4 v4.18.2/go.mod h1:2CM6tJvn2kqPXwnXO/d3rAQYiyoIm180VsO8PRX6Rpk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -294,8 +294,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/redis/go-redis/v9 v9.7.2 h1:PSGhv13dJyrTCw1+55H0pIKM3WFov7HuUrKUmInGL0o= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
github.com/redis/go-redis/v9 v9.7.2/go.mod h1:yp5+a5FnEEP0/zTYuw6u6/2nn3zivwhv274qYgWQhDM= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=

View File

@ -14,6 +14,7 @@ func StartInitSystemConfig(svc *svc.ServiceContext) {
Subscribe(svc) Subscribe(svc)
Register(svc) Register(svc)
Mobile(svc) Mobile(svc)
TrafficDataToRedis(svc)
if !svc.Config.Debug { if !svc.Config.Debug {
Telegram(svc) Telegram(svc)
} }

View File

@ -91,6 +91,7 @@ CREATE TABLE IF NOT EXISTS `auth_method`
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `uni_auth_method` (`method`) UNIQUE KEY `uni_auth_method` (`method`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 9
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -304,6 +305,7 @@ CREATE TABLE IF NOT EXISTS `subscribe_type`
`updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间', `updated_at` datetime(3) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 15
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -321,6 +323,7 @@ CREATE TABLE IF NOT EXISTS `system`
UNIQUE KEY `uni_system_key` (`key`), UNIQUE KEY `uni_system_key` (`key`),
KEY `index_key` (`key`) KEY `index_key` (`key`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 42
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -395,6 +398,7 @@ CREATE TABLE IF NOT EXISTS `user`
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `idx_referer` (`referer_id`) KEY `idx_referer` (`referer_id`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 2
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;
@ -411,6 +415,7 @@ CREATE TABLE IF NOT EXISTS `user_auth_methods`
UNIQUE KEY `idx_auth_identifier` (`auth_identifier`), UNIQUE KEY `idx_auth_identifier` (`auth_identifier`),
KEY `idx_user_id` (`user_id`) KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB ) ENGINE = InnoDB
AUTO_INCREMENT = 2
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci; COLLATE = utf8mb4_general_ci;

File diff suppressed because one or more lines are too long

View File

@ -1,4 +0,0 @@
INSERT IGNORE INTO `system` (`id`, `category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUES
(42, 'subscribe', 'UserAgentLimit', 'false', 'bool', 'User Agent Limit', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
(43, 'subscribe', 'UserAgentList', '', 'string', 'User Agent List', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637');

View File

@ -1,3 +0,0 @@
DROP TABLE IF EXISTS `application`;
DROP TABLE IF EXISTS `application_version`;
DROP TABLE IF EXISTS `application_config`;

View File

@ -1,106 +0,0 @@
CREATE TABLE IF NOT EXISTS `user_balance_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`amount` bigint NOT NULL COMMENT 'Amount',
`type` tinyint(1) NOT NULL COMMENT 'Type: 1: Recharge 2: Withdraw 3: Payment 4: Refund 5: Reward',
`order_id` bigint DEFAULT NULL COMMENT 'Order ID',
`balance` bigint NOT NULL COMMENT 'Balance',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_commission_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`order_no` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Order No.',
`amount` bigint NOT NULL COMMENT 'Amount',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_gift_amount_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`user_subscribe_id` bigint DEFAULT NULL COMMENT 'Deduction User Subscribe ID',
`order_no` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Order No.',
`type` tinyint(1) NOT NULL COMMENT 'Type: 1: Increase 2: Reduce',
`amount` bigint NOT NULL COMMENT 'Amount',
`balance` bigint NOT NULL COMMENT 'Balance',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Remark',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_login_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`login_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Login IP',
`user_agent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'UserAgent',
`success` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Login Success',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_reset_subscribe_log`
(
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` BIGINT NOT NULL COMMENT 'User ID',
`type` TINYINT(1) NOT NULL COMMENT 'Type: 1: Auto 2: Advance 3: Paid',
`order_no` VARCHAR(255) DEFAULT NULL COMMENT 'Order No.',
`user_subscribe_id` BIGINT NOT NULL COMMENT 'User Subscribe ID',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
INDEX `idx_user_id` (`user_id`),
INDEX `idx_user_subscribe_id` (`user_subscribe_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `user_subscribe_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT 'User ID',
`user_subscribe_id` bigint NOT NULL COMMENT 'User Subscribe ID',
`token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Token',
`ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'IP',
`user_agent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'UserAgent',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_user_subscribe_id` (`user_subscribe_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `message_log`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'email' COMMENT 'Message Type',
`platform` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'smtp' COMMENT 'Platform',
`to` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'To',
`subject` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Subject',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'Content',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Status',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
DROP TABLE IF EXISTS `system_logs`;

View File

@ -1,19 +0,0 @@
DROP TABLE IF EXISTS `user_balance_log`;
DROP TABLE IF EXISTS `user_commission_log`;
DROP TABLE IF EXISTS `user_gift_amount_log`;
DROP TABLE IF EXISTS `user_login_log`;
DROP TABLE IF EXISTS `user_reset_subscribe_log`;
DROP TABLE IF EXISTS `user_subscribe_log`;
DROP TABLE IF EXISTS `message_log`;
DROP TABLE IF EXISTS `system_logs`;
CREATE TABLE `system_logs` (
`id` bigint NOT NULL AUTO_INCREMENT,
`type` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Log Type: 1: Email Message 2: Mobile Message 3: Subscribe 4: Subscribe Traffic 5: Server Traffic 6: Login 7: Register 8: Balance 9: Commission 10: Reset Subscribe 11: Gift',
`date` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Log Date',
`object_id` bigint NOT NULL DEFAULT '0' COMMENT 'Object ID',
`content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Log Content',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Create Time',
PRIMARY KEY (`id`),
KEY `idx_type` (`type`),
KEY `idx_object_id` (`object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -1,2 +0,0 @@
DROP TABLE IF EXISTS `nodes`;
DROP TABLE IF EXISTS `servers`;

View File

@ -1,28 +0,0 @@
CREATE TABLE IF NOT EXISTS `servers` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Server Name',
`country` varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Country',
`city` varchar(128) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'City',
`ratio` decimal(4,2) NOT NULL DEFAULT '0.00' COMMENT 'Traffic Ratio',
`address` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Server Address',
`sort` bigint NOT NULL DEFAULT '0' COMMENT 'Sort',
`protocols` text COLLATE utf8mb4_general_ci COMMENT 'Protocol',
`last_reported_at` datetime(3) DEFAULT NULL COMMENT 'Last Reported Time',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `nodes` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Node Name',
`tags` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Tags',
`port` smallint unsigned NOT NULL DEFAULT '0' COMMENT 'Connect Port',
`address` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Connect Address',
`server_id` bigint NOT NULL DEFAULT '0' COMMENT 'Server ID',
`protocol` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Protocol',
`enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Enabled',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -1,5 +0,0 @@
ALTER TABLE `subscribe`
DROP COLUMN `nodes`,
DROP COLUMN `node_tags`,
ADD COLUMN `server` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Server',
ADD COLUMN `server_group` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Server Group';

View File

@ -1,7 +0,0 @@
ALTER TABLE `subscribe`
ADD COLUMN `nodes` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Node IDs',
ADD COLUMN `node_tags` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Node Tags',
DROP COLUMN `server`,
DROP COLUMN `server_group`;
DROP TABLE IF EXISTS `server_rule_group`;

View File

@ -1,4 +0,0 @@
INSERT IGNORE INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
VALUES
('log', 'AutoClear', 'true', 'bool', 'Auto Clear Log', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'),
('log', 'ClearDays', '7', 'int', 'Clear Days', '2025-04-22 14:25:16.637','2025-04-22 14:25:16.637');

View File

@ -1,3 +0,0 @@
ALTER TABLE `user`
DROP COLUMN `referral_percentage`,
DROP COLUMN `only_first_purchase`;

View File

@ -1,7 +0,0 @@
ALTER TABLE `user`
ADD COLUMN `referral_percentage` TINYINT UNSIGNED NOT NULL DEFAULT 0
COMMENT 'Referral Percentage'
AFTER `commission`,
ADD COLUMN `only_first_purchase` TINYINT(1) NOT NULL DEFAULT 1
COMMENT 'Only First Purchase'
AFTER `referral_percentage`;

View File

@ -1,2 +0,0 @@
ALTER TABLE `nodes`
DROP COLUMN `sort`;

View File

@ -1,3 +0,0 @@
ALTER TABLE `nodes`
ADD COLUMN `sort` INT UNSIGNED NOT NULL DEFAULT 0
COMMENT 'Sort' AFTER `enabled`;

View File

@ -1 +0,0 @@
DROP INDEX idx_traffic_log_time_user_sub ON traffic_log;

View File

@ -1 +0,0 @@
CREATE INDEX idx_traffic_log_time_user_sub ON traffic_log (timestamp, user_id, subscribe_id);

View File

@ -1,2 +0,0 @@
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `sms`;

View File

@ -1,2 +0,0 @@
DROP TABLE IF EXISTS `subscribe_type`;
DROP TABLE IF EXISTS `sms`;

View File

@ -1,7 +0,0 @@
ALTER TABLE `subscribe`
DROP COLUMN `group_id`,
ADD COLUMN `language` VARCHAR(255) NOT NULL DEFAULT ''
COMMENT 'Language'
AFTER `name`;
DROP TABLE IF EXISTS `subscribe_group`;

View File

@ -1,14 +0,0 @@
DROP TABLE IF EXISTS `email_task`;
CREATE TABLE `task` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`type` tinyint NOT NULL COMMENT 'Task Type',
`scope` text COLLATE utf8mb4_general_ci COMMENT 'Task Scope',
`content` text COLLATE utf8mb4_general_ci COMMENT 'Task Content',
`status` tinyint NOT NULL DEFAULT '0' COMMENT 'Task Status: 0: Pending, 1: In Progress, 2: Completed, 3: Failed',
`errors` text COLLATE utf8mb4_general_ci COMMENT 'Task Errors',
`total` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Total Number',
`current` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Current Number',
`created_at` datetime(3) DEFAULT NULL COMMENT 'Creation Time',
`updated_at` datetime(3) DEFAULT NULL COMMENT 'Update Time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -3,10 +3,7 @@ package migrate
import ( import (
"testing" "testing"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/pkg/orm" "github.com/perfect-panel/server/pkg/orm"
"gorm.io/driver/mysql"
"gorm.io/gorm"
) )
func getDSN() string { func getDSN() string {
@ -33,17 +30,3 @@ func TestMigrate(t *testing.T) {
t.Log("migrate success") t.Log("migrate success")
} }
} }
func TestMysql(t *testing.T) {
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:mylove520@tcp(localhost:3306)/vpnboard",
}))
if err != nil {
t.Fatalf("Failed to connect to MySQL: %v", err)
}
err = db.Migrator().AutoMigrate(&node.Node{})
if err != nil {
t.Fatalf("Failed to auto migrate: %v", err)
return
}
t.Log("MySQL connection and migration successful")
}

57
initialize/statistics.go Normal file
View File

@ -0,0 +1,57 @@
package initialize
import (
"context"
"time"
"github.com/perfect-panel/server/internal/model/cache"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/logger"
)
func TrafficDataToRedis(svcCtx *svc.ServiceContext) {
ctx := context.Background()
// 统计昨天的节点流量数据排行榜前10
nodeData, err := svcCtx.TrafficLogModel.TopServersTrafficByDay(ctx, time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day()-1, 0, 0, 0, 0, time.Local), 10)
if err != nil {
logger.Errorw("统计昨天的流量数据失败", logger.Field("error", err.Error()))
}
var nodeCacheData []cache.NodeTodayTrafficRank
for _, node := range nodeData {
serverInfo, err := svcCtx.ServerModel.FindOne(ctx, node.ServerId)
if err != nil {
logger.Errorw("查询节点信息失败", logger.Field("error", err.Error()))
continue
}
nodeCacheData = append(nodeCacheData, cache.NodeTodayTrafficRank{
ID: node.ServerId,
Name: serverInfo.Name,
Upload: node.Upload,
Download: node.Download,
Total: node.Upload + node.Download,
})
}
// 写入缓存
if err = svcCtx.NodeCache.UpdateYesterdayNodeTotalTrafficRank(ctx, nodeCacheData); err != nil {
logger.Errorw("写入昨天的流量数据到缓存失败", logger.Field("error", err.Error()))
}
// 统计昨天的用户流量数据排行榜前10
userData, err := svcCtx.TrafficLogModel.TopUsersTrafficByDay(ctx, time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day()-1, 0, 0, 0, 0, time.Local), 10)
if err != nil {
logger.Errorw("统计昨天的流量数据失败", logger.Field("error", err.Error()))
}
var userCacheData []cache.UserTodayTrafficRank
for _, user := range userData {
userCacheData = append(userCacheData, cache.UserTodayTrafficRank{
SID: user.SubscribeId,
Upload: user.Upload,
Download: user.Download,
Total: user.Upload + user.Download,
})
}
// 写入缓存
if err = svcCtx.NodeCache.UpdateYesterdayUserTotalTrafficRank(ctx, userCacheData); err != nil {
logger.Errorw("写入昨天的流量数据到缓存失败", logger.Field("error", err.Error()))
}
logger.Infow("初始化昨天的流量数据到缓存成功")
}

View File

@ -12,6 +12,9 @@ const SiteConfigKey = "system:site_config"
// SubscribeConfigKey Subscribe Config Key // SubscribeConfigKey Subscribe Config Key
const SubscribeConfigKey = "system:subscribe_config" const SubscribeConfigKey = "system:subscribe_config"
// ApplicationKey Application Key
const ApplicationKey = "system:application"
// RegisterConfigKey Register Config Key // RegisterConfigKey Register Config Key
const RegisterConfigKey = "system:register_config" const RegisterConfigKey = "system:register_config"
@ -48,12 +51,26 @@ const AuthCodeCacheKey = "auth:verify:email"
// AuthCodeTelephoneCacheKey Register Code Cache Key // AuthCodeTelephoneCacheKey Register Code Cache Key
const AuthCodeTelephoneCacheKey = "auth:verify:telephone" const AuthCodeTelephoneCacheKey = "auth:verify:telephone"
// CommonStatCacheKey CommonStat Cache Key // ServerUserListCacheKey Server User List Cache Key
const ServerUserListCacheKey = "server:user_list:id:"
// ServerConfigCacheKey Server Config Cache Key
const ServerConfigCacheKey = "server:config:id:"
// CommonStat Cache Key
const CommonStatCacheKey = "common:stat" const CommonStatCacheKey = "common:stat"
// ServerStatusCacheKey Server Status Cache Key
const ServerStatusCacheKey = "server:status:id:"
// ServerCountCacheKey Server Count Cache Key // ServerCountCacheKey Server Count Cache Key
const ServerCountCacheKey = "server:count" const ServerCountCacheKey = "server:count"
// UserBindTelegramCacheKey User Bind Telegram Cache Key
const UserBindTelegramCacheKey = "user:bind:telegram:code:"
const CacheSmsCount = "cache:sms:count"
// SendIntervalKeyPrefix Auth Code Send Interval Key Prefix // SendIntervalKeyPrefix Auth Code Send Interval Key Prefix
const SendIntervalKeyPrefix = "send:interval:" const SendIntervalKeyPrefix = "send:interval:"

View File

@ -25,7 +25,6 @@ type Config struct {
Subscribe SubscribeConfig `yaml:"Subscribe"` Subscribe SubscribeConfig `yaml:"Subscribe"`
Invite InviteConfig `yaml:"Invite"` Invite InviteConfig `yaml:"Invite"`
Telegram Telegram `yaml:"Telegram"` Telegram Telegram `yaml:"Telegram"`
Log Log `yaml:"Log"`
Administrator struct { Administrator struct {
Email string `yaml:"Email" default:"admin@ppanel.dev"` Email string `yaml:"Email" default:"admin@ppanel.dev"`
Password string `yaml:"Password" default:"password"` Password string `yaml:"Password" default:"password"`
@ -53,11 +52,9 @@ type Verify struct {
type SubscribeConfig struct { type SubscribeConfig struct {
SingleModel bool `yaml:"SingleModel" default:"false"` SingleModel bool `yaml:"SingleModel" default:"false"`
SubscribePath string `yaml:"SubscribePath" default:"/v1/subscribe/config"` SubscribePath string `yaml:"SubscribePath" default:"/api/subscribe"`
SubscribeDomain string `yaml:"SubscribeDomain" default:""` SubscribeDomain string `yaml:"SubscribeDomain" default:""`
PanDomain bool `yaml:"PanDomain" default:"false"` PanDomain bool `yaml:"PanDomain" default:"false"`
UserAgentLimit bool `yaml:"UserAgentLimit" default:"false"`
UserAgentList string `yaml:"UserAgentList" default:""`
} }
type RegisterConfig struct { type RegisterConfig struct {
@ -147,8 +144,3 @@ type VerifyCode struct {
Limit int64 `yaml:"Limit" default:"15"` Limit int64 `yaml:"Limit" default:"15"`
Interval int64 `yaml:"Interval" default:"60"` Interval int64 `yaml:"Interval" default:"60"`
} }
type Log struct {
AutoClear bool `yaml:"AutoClear" default:"true"`
ClearDays int64 `yaml:"ClearDays" default:"7"`
}

View File

@ -1,26 +0,0 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter reset subscribe log
func FilterResetSubscribeLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterResetSubscribeLogRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterResetSubscribeLogLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterResetSubscribeLog(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,26 +0,0 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter subscribe log
func FilterSubscribeLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterSubscribeLogRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterSubscribeLogLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterSubscribeLog(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,26 +0,0 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter traffic log details
func FilterTrafficLogDetailsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterTrafficLogDetailsRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterTrafficLogDetailsLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterTrafficLogDetails(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,26 +0,0 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Filter user subscribe traffic log
func FilterUserSubscribeTrafficLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterSubscribeTrafficRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := log.NewFilterUserSubscribeTrafficLogLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterUserSubscribeTrafficLog(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,18 +0,0 @@
package log
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/log"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/result"
)
// Get log setting
func GetLogSettingHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
l := log.NewGetLogSettingLogic(c.Request.Context(), svcCtx)
resp, err := l.GetLogSetting()
result.HttpResult(c, resp, err)
}
}

View File

@ -1,26 +0,0 @@
package marketing
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/marketing"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Query quota task list
func QueryQuotaTaskListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.QueryQuotaTaskListRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := marketing.NewQueryQuotaTaskListLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryQuotaTaskList(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -1,26 +0,0 @@
package marketing
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/marketing"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Query quota task status
func QueryQuotaTaskStatusHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.QueryQuotaTaskStatusRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := marketing.NewQueryQuotaTaskStatusLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryQuotaTaskStatus(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -0,0 +1,26 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Batch delete node group
func BatchDeleteNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.BatchDeleteNodeGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewBatchDeleteNodeGroupLogic(c.Request.Context(), svcCtx)
err := l.BatchDeleteNodeGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Delete Server // Batch delete node
func DeleteServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func BatchDeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.DeleteServerRequest var req types.BatchDeleteNodeRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func DeleteServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewDeleteServerLogic(c.Request.Context(), svcCtx) l := server.NewBatchDeleteNodeLogic(c.Request.Context(), svcCtx)
err := l.DeleteServer(&req) err := l.BatchDeleteNode(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Reset node sort // Create node group
func ResetSortWithNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func CreateNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.ResetSortRequest var req types.CreateNodeGroupRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func ResetSortWithNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewResetSortWithNodeLogic(c.Request.Context(), svcCtx) l := server.NewCreateNodeGroupLogic(c.Request.Context(), svcCtx)
err := l.ResetSortWithNode(&req) err := l.CreateNodeGroup(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Create Node // Create node
func CreateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func CreateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CreateNodeRequest var req types.CreateNodeRequest

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Reset server sort // CreateRuleGroupHandler Create rule group
func ResetSortWithServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func CreateRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.ResetSortRequest var req types.CreateRuleGroupRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func ResetSortWithServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context)
return return
} }
l := server.NewResetSortWithServerLogic(c.Request.Context(), svcCtx) l := server.NewCreateRuleGroupLogic(c.Request.Context(), svcCtx)
err := l.ResetSortWithServer(&req) err := l.CreateRuleGroup(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// CreateServerHandler Create Server // Delete node group
func CreateServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func DeleteNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CreateServerRequest var req types.DeleteNodeGroupRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func CreateServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewCreateServerLogic(c.Request.Context(), svcCtx) l := server.NewDeleteNodeGroupLogic(c.Request.Context(), svcCtx)
err := l.CreateServer(&req) err := l.DeleteNodeGroup(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Delete Node // Delete node
func DeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func DeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.DeleteNodeRequest var req types.DeleteNodeRequest

View File

@ -0,0 +1,26 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Delete rule group
func DeleteRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.DeleteRuleGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewDeleteRuleGroupLogic(c.Request.Context(), svcCtx)
err := l.DeleteRuleGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -1,26 +0,0 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// FilterServerListHandler Filter Server List
func FilterServerListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.FilterServerListRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewFilterServerListLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterServerList(&req)
result.HttpResult(c, resp, err)
}
}

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Filter Node List // Get node detail
func FilterNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func GetNodeDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.FilterNodeListRequest var req types.GetDetailRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func FilterNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewFilterNodeListLogic(c.Request.Context(), svcCtx) l := server.NewGetNodeDetailLogic(c.Request.Context(), svcCtx)
resp, err := l.FilterNodeList(&req) resp, err := l.GetNodeDetail(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -7,12 +7,12 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Migrate server and node data to new database // Get node group list
func MigrateServerNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func GetNodeGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
l := server.NewMigrateServerNodeLogic(c.Request.Context(), svcCtx) l := server.NewGetNodeGroupListLogic(c.Request.Context(), svcCtx)
resp, err := l.MigrateServerNode() resp, err := l.GetNodeGroupList()
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Get Server Protocols // Get node list
func GetServerProtocolsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.GetServerProtocolsRequest var req types.GetNodeServerListRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func GetServerProtocolsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context)
return return
} }
l := server.NewGetServerProtocolsLogic(c.Request.Context(), svcCtx) l := server.NewGetNodeListLogic(c.Request.Context(), svcCtx)
resp, err := l.GetServerProtocols(&req) resp, err := l.GetNodeList(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -7,12 +7,12 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Query all node tags // Get node tag list
func QueryNodeTagHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func GetNodeTagListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
l := server.NewQueryNodeTagLogic(c.Request.Context(), svcCtx) l := server.NewGetNodeTagListLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryNodeTag() resp, err := l.GetNodeTagList()
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -7,12 +7,12 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Check if there is any server or node to migrate // Get rule group list
func HasMigrateSeverNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func GetRuleGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
l := server.NewHasMigrateSeverNodeLogic(c.Request.Context(), svcCtx) l := server.NewGetRuleGroupListLogic(c.Request.Context(), svcCtx)
resp, err := l.HasMigrateSeverNode() resp, err := l.GetRuleGroupList()
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Update Server // Node sort
func UpdateServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func NodeSortHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.UpdateServerRequest var req types.NodeSortRequest
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func UpdateServerHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := server.NewUpdateServerLogic(c.Request.Context(), svcCtx) l := server.NewNodeSortLogic(c.Request.Context(), svcCtx)
err := l.UpdateServer(&req) err := l.NodeSort(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -1,26 +0,0 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Toggle Node Status
func ToggleNodeStatusHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.ToggleNodeStatusRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewToggleNodeStatusLogic(c.Request.Context(), svcCtx)
err := l.ToggleNodeStatus(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,26 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Update node group
func UpdateNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UpdateNodeGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewUpdateNodeGroupLogic(c.Request.Context(), svcCtx)
err := l.UpdateNodeGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -8,7 +8,7 @@ import (
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Update Node // Update node
func UpdateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func UpdateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.UpdateNodeRequest var req types.UpdateNodeRequest

View File

@ -0,0 +1,26 @@
package server
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/server"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Update rule group
func UpdateRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UpdateRuleGroupRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := server.NewUpdateRuleGroupLogic(c.Request.Context(), svcCtx)
err := l.UpdateRuleGroup(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,26 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Create application
func CreateApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.CreateApplicationRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := system.NewCreateApplicationLogic(c.Request.Context(), svcCtx)
err := l.CreateApplication(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,26 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Create application version
func CreateApplicationVersionHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.CreateApplicationVersionRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := system.NewCreateApplicationVersionLogic(c.Request.Context(), svcCtx)
err := l.CreateApplicationVersion(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,26 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Delete application
func DeleteApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.DeleteApplicationRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := system.NewDeleteApplicationLogic(c.Request.Context(), svcCtx)
err := l.DeleteApplication(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,26 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Delete application
func DeleteApplicationVersionHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.DeleteApplicationVersionRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := system.NewDeleteApplicationVersionLogic(c.Request.Context(), svcCtx)
err := l.DeleteApplicationVersion(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,18 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/result"
)
// get application config
func GetApplicationConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
l := system.NewGetApplicationConfigLogic(c.Request.Context(), svcCtx)
resp, err := l.GetApplicationConfig()
result.HttpResult(c, resp, err)
}
}

View File

@ -0,0 +1,18 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/result"
)
// Get application
func GetApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
l := system.NewGetApplicationLogic(c.Request.Context(), svcCtx)
resp, err := l.GetApplication()
result.HttpResult(c, resp, err)
}
}

View File

@ -0,0 +1,18 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/result"
)
// Get subscribe type
func GetSubscribeTypeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
l := system.NewGetSubscribeTypeLogic(c.Request.Context(), svcCtx)
resp, err := l.GetSubscribeType()
result.HttpResult(c, resp, err)
}
}

View File

@ -1,17 +1,17 @@
package marketing package system
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/marketing" "github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
// Create a quota task // update application config
func CreateQuotaTaskHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func UpdateApplicationConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.CreateQuotaTaskRequest var req types.ApplicationConfig
_ = c.ShouldBind(&req) _ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req) validateErr := svcCtx.Validate(&req)
if validateErr != nil { if validateErr != nil {
@ -19,8 +19,8 @@ func CreateQuotaTaskHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return return
} }
l := marketing.NewCreateQuotaTaskLogic(c.Request.Context(), svcCtx) l := system.NewUpdateApplicationConfigLogic(c.Request.Context(), svcCtx)
err := l.CreateQuotaTask(&req) err := l.UpdateApplicationConfig(&req)
result.HttpResult(c, nil, err) result.HttpResult(c, nil, err)
} }
} }

View File

@ -0,0 +1,26 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Update application
func UpdateApplicationHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UpdateApplicationRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := system.NewUpdateApplicationLogic(c.Request.Context(), svcCtx)
err := l.UpdateApplication(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -0,0 +1,26 @@
package system
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/system"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Update application version
func UpdateApplicationVersionHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UpdateApplicationVersionRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := system.NewUpdateApplicationVersionLogic(c.Request.Context(), svcCtx)
err := l.UpdateApplicationVersion(&req)
result.HttpResult(c, nil, err)
}
}

View File

@ -1,26 +0,0 @@
package user
import (
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/admin/user"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result"
)
// Get user subcribe reset traffic logs
func GetUserSubscribeResetTrafficLogsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.GetUserSubscribeResetTrafficLogsRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := user.NewGetUserSubscribeResetTrafficLogsLogic(c.Request.Context(), svcCtx)
resp, err := l.GetUserSubscribeResetTrafficLogs(&req)
result.HttpResult(c, resp, err)
}
}

Some files were not shown because too many files have changed in this diff Show More