refactor: 更新项目引用路径从perfect-panel/ppanel-server到perfect-panel/server

feat: 添加版本和构建时间变量
fix: 修正短信队列类型注释错误
style: 清理未使用的代码和测试文件
docs: 更新安装文档中的下载链接
chore: 迁移数据库脚本添加日志和订阅配置
This commit is contained in:
2025-10-13 01:33:03 -07:00
parent 393b42f35a
commit c582087c0f
974 changed files with 23609 additions and 23398 deletions
+84 -1
View File
@@ -1,3 +1,86 @@
package server
const Unchanged = "Unchanged"
const (
Unchanged = "Unchanged"
ShadowSocks = "shadowsocks"
Vmess = "vmess"
Vless = "vless"
Trojan = "trojan"
AnyTLS = "anytls"
Tuic = "tuic"
Hysteria = "hysteria"
// Deprecated: Hysteria2 is deprecated, use Hysteria instead
// TODO: remove in future versions
Hysteria2 = "hysteria2"
)
type SecurityConfig struct {
SNI string `json:"sni"`
AllowInsecure *bool `json:"allow_insecure"`
Fingerprint string `json:"fingerprint"`
RealityServerAddress string `json:"reality_server_addr"`
RealityServerPort int `json:"reality_server_port"`
RealityPrivateKey string `json:"reality_private_key"`
RealityPublicKey string `json:"reality_public_key"`
RealityShortId string `json:"reality_short_id"`
RealityMldsa65seed string `json:"reality_mldsa65seed"`
}
type TransportConfig struct {
Path string `json:"path"`
Host string `json:"host"`
ServiceName string `json:"service_name"`
DisableSNI bool `json:"disable_sni"`
ReduceRtt bool `json:"reduce_rtt"`
UDPRelayMode string `json:"udp_relay_mode"`
CongestionController string `json:"congestion_controller"`
}
type VlessNode struct {
Port uint16 `json:"port"`
Flow string `json:"flow"`
Network string `json:"transport"`
TransportConfig *TransportConfig `json:"transport_config"`
Security string `json:"security"`
SecurityConfig *SecurityConfig `json:"security_config"`
}
type VmessNode struct {
Port uint16 `json:"port"`
Network string `json:"transport"`
TransportConfig *TransportConfig `json:"transport_config"`
Security string `json:"security"`
SecurityConfig *SecurityConfig `json:"security_config"`
}
type ShadowsocksNode struct {
Port uint16 `json:"port"`
Cipher string `json:"method"`
ServerKey string `json:"server_key"`
}
type TrojanNode struct {
Port uint16 `json:"port"`
Network string `json:"transport"`
TransportConfig *TransportConfig `json:"transport_config"`
Security string `json:"security"`
SecurityConfig *SecurityConfig `json:"security_config"`
}
type AnyTLSNode struct {
Port uint16 `json:"port"`
SecurityConfig *SecurityConfig `json:"security_config"`
}
type TuicNode struct {
Port uint16 `json:"port"`
SecurityConfig *SecurityConfig `json:"security_config"`
}
type Hysteria2Node struct {
Port uint16 `json:"port"`
HopPorts string `json:"hop_ports"`
HopInterval int `json:"hop_interval"`
ObfsPassword string `json:"obfs_password"`
SecurityConfig *SecurityConfig `json:"security_config"`
}
+175 -17
View File
@@ -1,17 +1,18 @@
package server
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/ppanel-server/internal/config"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/tool"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/tool"
"github.com/perfect-panel/server/pkg/xerr"
)
type GetServerConfigLogic struct {
@@ -20,7 +21,7 @@ type GetServerConfigLogic struct {
svcCtx *svc.ServiceContext
}
// Get server config
// NewGetServerConfigLogic Get server config
func NewGetServerConfigLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *GetServerConfigLogic {
return &GetServerConfigLogic{
Logger: logger.WithContext(ctx.Request.Context()),
@@ -30,7 +31,7 @@ func NewGetServerConfigLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *GetS
}
func (l *GetServerConfigLogic) GetServerConfig(req *types.GetServerConfigRequest) (resp *types.GetServerConfigResponse, err error) {
cacheKey := fmt.Sprintf("%s%d", config.ServerConfigCacheKey, req.ServerId)
cacheKey := fmt.Sprintf("%s%d:%s", node.ServerConfigCacheKey, req.ServerId, req.Protocol)
cache, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
if err == nil {
if cache != "" {
@@ -41,7 +42,7 @@ func (l *GetServerConfigLogic) GetServerConfig(req *types.GetServerConfigRequest
return nil, xerr.StatusNotModified
}
l.ctx.Header("ETag", etag)
resp := &types.GetServerConfigResponse{}
resp = &types.GetServerConfigResponse{}
err = json.Unmarshal([]byte(cache), resp)
if err != nil {
l.Errorw("[ServerConfigCacheKey] json unmarshal error", logger.Field("error", err.Error()))
@@ -50,34 +51,191 @@ func (l *GetServerConfigLogic) GetServerConfig(req *types.GetServerConfigRequest
return resp, nil
}
}
nodeInfo, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.ServerId)
data, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerId)
if err != nil {
l.Errorw("[GetServerConfig] FindOne error", logger.Field("error", err.Error()))
return nil, err
}
cfg := make(map[string]interface{})
err = json.Unmarshal([]byte(nodeInfo.Config), &cfg)
// compatible hysteria2, remove in future versions
protocolRequest := req.Protocol
if protocolRequest == Hysteria2 {
protocolRequest = Hysteria
}
protocols, err := data.UnmarshalProtocols()
if err != nil {
l.Errorw("[GetServerConfig] json unmarshal error", logger.Field("error", err.Error()))
return nil, err
}
var cfg map[string]interface{}
for _, protocol := range protocols {
if protocol.Type == protocolRequest {
cfg = l.compatible(protocol)
break
}
}
resp = &types.GetServerConfigResponse{
Basic: types.ServerBasic{
PullInterval: l.svcCtx.Config.Node.NodePullInterval,
PushInterval: l.svcCtx.Config.Node.NodePushInterval,
},
Protocol: nodeInfo.Protocol,
Protocol: req.Protocol,
Config: cfg,
}
data, err := json.Marshal(resp)
c, err := json.Marshal(resp)
if err != nil {
l.Errorw("[GetServerConfig] json marshal error", logger.Field("error", err.Error()))
return nil, err
}
etag := tool.GenerateETag(data)
etag := tool.GenerateETag(c)
l.ctx.Header("ETag", etag)
if err = l.svcCtx.Redis.Set(l.ctx, cacheKey, data, -1).Err(); err != nil {
if err = l.svcCtx.Redis.Set(l.ctx, cacheKey, c, -1).Err(); err != nil {
l.Errorw("[GetServerConfig] redis set error", logger.Field("error", err.Error()))
}
// Check If-None-Match header
match := l.ctx.GetHeader("If-None-Match")
if match == etag {
return nil, xerr.StatusNotModified
}
return resp, nil
}
func (l *GetServerConfigLogic) compatible(config node.Protocol) map[string]interface{} {
var result interface{}
switch config.Type {
case ShadowSocks:
result = ShadowsocksNode{
Port: config.Port,
Cipher: config.Cipher,
ServerKey: base64.StdEncoding.EncodeToString([]byte(config.ServerKey)),
}
case Vless:
result = VlessNode{
Port: config.Port,
Flow: config.Flow,
Network: config.Transport,
TransportConfig: &TransportConfig{
Path: config.Path,
Host: config.Host,
ServiceName: config.ServiceName,
DisableSNI: config.DisableSNI,
ReduceRtt: config.ReduceRtt,
UDPRelayMode: config.UDPRelayMode,
CongestionController: config.CongestionController,
},
Security: config.Security,
SecurityConfig: &SecurityConfig{
SNI: config.SNI,
AllowInsecure: &config.AllowInsecure,
Fingerprint: config.Fingerprint,
RealityServerAddress: config.RealityServerAddr,
RealityServerPort: config.RealityServerPort,
RealityPrivateKey: config.RealityPrivateKey,
RealityPublicKey: config.RealityPublicKey,
RealityShortId: config.RealityShortId,
},
}
case Vmess:
result = VmessNode{
Port: config.Port,
Network: config.Transport,
TransportConfig: &TransportConfig{
Path: config.Path,
Host: config.Host,
ServiceName: config.ServiceName,
DisableSNI: config.DisableSNI,
ReduceRtt: config.ReduceRtt,
UDPRelayMode: config.UDPRelayMode,
CongestionController: config.CongestionController,
},
Security: config.Security,
SecurityConfig: &SecurityConfig{
SNI: config.SNI,
AllowInsecure: &config.AllowInsecure,
Fingerprint: config.Fingerprint,
RealityServerAddress: config.RealityServerAddr,
RealityServerPort: config.RealityServerPort,
RealityPrivateKey: config.RealityPrivateKey,
RealityPublicKey: config.RealityPublicKey,
RealityShortId: config.RealityShortId,
},
}
case Trojan:
result = TrojanNode{
Port: config.Port,
Network: config.Transport,
TransportConfig: &TransportConfig{
Path: config.Path,
Host: config.Host,
ServiceName: config.ServiceName,
DisableSNI: config.DisableSNI,
ReduceRtt: config.ReduceRtt,
UDPRelayMode: config.UDPRelayMode,
CongestionController: config.CongestionController,
},
Security: config.Security,
SecurityConfig: &SecurityConfig{
SNI: config.SNI,
AllowInsecure: &config.AllowInsecure,
Fingerprint: config.Fingerprint,
RealityServerAddress: config.RealityServerAddr,
RealityServerPort: config.RealityServerPort,
RealityPrivateKey: config.RealityPrivateKey,
RealityPublicKey: config.RealityPublicKey,
RealityShortId: config.RealityShortId,
},
}
case AnyTLS:
result = AnyTLSNode{
Port: config.Port,
SecurityConfig: &SecurityConfig{
SNI: config.SNI,
AllowInsecure: &config.AllowInsecure,
Fingerprint: config.Fingerprint,
RealityServerAddress: config.RealityServerAddr,
RealityServerPort: config.RealityServerPort,
RealityPrivateKey: config.RealityPrivateKey,
RealityPublicKey: config.RealityPublicKey,
RealityShortId: config.RealityShortId,
},
}
case Tuic:
result = TuicNode{
Port: config.Port,
SecurityConfig: &SecurityConfig{
SNI: config.SNI,
AllowInsecure: &config.AllowInsecure,
Fingerprint: config.Fingerprint,
RealityServerAddress: config.RealityServerAddr,
RealityServerPort: config.RealityServerPort,
RealityPrivateKey: config.RealityPrivateKey,
RealityPublicKey: config.RealityPublicKey,
RealityShortId: config.RealityShortId,
},
}
case Hysteria:
result = Hysteria2Node{
Port: config.Port,
HopPorts: config.HopPorts,
HopInterval: config.HopInterval,
ObfsPassword: config.ObfsPassword,
SecurityConfig: &SecurityConfig{
SNI: config.SNI,
AllowInsecure: &config.AllowInsecure,
Fingerprint: config.Fingerprint,
RealityServerAddress: config.RealityServerAddr,
RealityServerPort: config.RealityServerPort,
RealityPrivateKey: config.RealityPrivateKey,
RealityPublicKey: config.RealityPublicKey,
RealityShortId: config.RealityShortId,
},
}
}
var resp map[string]interface{}
s, _ := json.Marshal(result)
_ = json.Unmarshal(s, &resp)
return resp
}
+56 -33
View File
@@ -3,16 +3,18 @@ package server
import (
"encoding/json"
"fmt"
"strings"
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/internal/model/subscribe"
"github.com/perfect-panel/ppanel-server/internal/config"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/tool"
"github.com/perfect-panel/ppanel-server/pkg/uuidx"
"github.com/perfect-panel/ppanel-server/pkg/xerr"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/tool"
"github.com/perfect-panel/server/pkg/uuidx"
"github.com/perfect-panel/server/pkg/xerr"
)
type GetServerUserListLogic struct {
@@ -21,7 +23,7 @@ type GetServerUserListLogic struct {
svcCtx *svc.ServiceContext
}
// Get user list
// NewGetServerUserListLogic Get user list
func NewGetServerUserListLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *GetServerUserListLogic {
return &GetServerUserListLogic{
Logger: logger.WithContext(ctx.Request.Context()),
@@ -31,30 +33,53 @@ func NewGetServerUserListLogic(ctx *gin.Context, svcCtx *svc.ServiceContext) *Ge
}
func (l *GetServerUserListLogic) GetServerUserList(req *types.GetServerUserListRequest) (resp *types.GetServerUserListResponse, err error) {
cacheKey := fmt.Sprintf("%s%d", config.ServerUserListCacheKey, req.ServerId)
cacheKey := fmt.Sprintf("%s%d", node.ServerUserListCacheKey, req.ServerId)
cache, err := l.svcCtx.Redis.Get(l.ctx, cacheKey).Result()
if err == nil {
if cache != "" {
etag := tool.GenerateETag([]byte(cache))
resp := &types.GetServerUserListResponse{}
// Check If-None-Match header
if match := l.ctx.GetHeader("If-None-Match"); match == etag {
return nil, xerr.StatusNotModified
}
l.ctx.Header("ETag", etag)
err = json.Unmarshal([]byte(cache), resp)
if err != nil {
l.Errorw("[ServerUserListCacheKey] json unmarshal error", logger.Field("error", err.Error()))
return nil, err
}
return resp, nil
if cache != "" {
etag := tool.GenerateETag([]byte(cache))
resp = &types.GetServerUserListResponse{}
// Check If-None-Match header
if match := l.ctx.GetHeader("If-None-Match"); match == etag {
return nil, xerr.StatusNotModified
}
l.ctx.Header("ETag", etag)
err = json.Unmarshal([]byte(cache), resp)
if err != nil {
l.Errorw("[ServerUserListCacheKey] json unmarshal error", logger.Field("error", err.Error()))
return nil, err
}
return resp, nil
}
server, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.ServerId)
server, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerId)
if err != nil {
return nil, err
}
subs, err := l.svcCtx.SubscribeModel.QuerySubscribeIdsByServerIdAndServerGroupId(l.ctx, server.Id, server.GroupId)
_, nodes, err := l.svcCtx.NodeModel.FilterNodeList(l.ctx, &node.FilterNodeParams{
Page: 1,
Size: 1000,
ServerId: []int64{server.Id},
Protocol: req.Protocol,
})
if err != nil {
l.Errorw("FilterNodeList error", logger.Field("error", err.Error()))
return nil, err
}
var nodeTag []string
var nodeIds []int64
for _, n := range nodes {
nodeIds = append(nodeIds, n.Id)
if n.Tags != "" {
nodeTag = append(nodeTag, strings.Split(n.Tags, ",")...)
}
}
_, subs, err := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
Page: 1,
Size: 9999,
Node: nodeIds,
Tags: nodeTag,
})
if err != nil {
l.Errorw("QuerySubscribeIdsByServerIdAndServerGroupId error", logger.Field("error", err.Error()))
return nil, err
@@ -76,16 +101,10 @@ func (l *GetServerUserListLogic) GetServerUserList(req *types.GetServerUserListR
return nil, err
}
for _, datum := range data {
speedLimit := server.SpeedLimit
if (int(sub.SpeedLimit) < server.SpeedLimit && sub.SpeedLimit != 0) ||
(int(sub.SpeedLimit) > server.SpeedLimit && sub.SpeedLimit == 0) {
speedLimit = int(sub.SpeedLimit)
}
users = append(users, types.ServerUser{
Id: datum.Id,
UUID: datum.UUID,
SpeedLimit: int64(speedLimit),
SpeedLimit: sub.SpeedLimit,
DeviceLimit: sub.DeviceLimit,
})
}
@@ -106,5 +125,9 @@ func (l *GetServerUserListLogic) GetServerUserList(req *types.GetServerUserListR
if err != nil {
l.Errorw("[ServerUserListCacheKey] redis set error", logger.Field("error", err.Error()))
}
// Check If-None-Match header
if match := l.ctx.GetHeader("If-None-Match"); match == etag {
return nil, xerr.StatusNotModified
}
return resp, nil
}
+16 -12
View File
@@ -5,10 +5,10 @@ import (
"errors"
"fmt"
"github.com/perfect-panel/ppanel-server/internal/model/cache"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
)
type PushOnlineUsersLogic struct {
@@ -40,26 +40,30 @@ func (l *PushOnlineUsersLogic) PushOnlineUsers(req *types.OnlineUsersRequest) er
}
// Find server info
_, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.ServerId)
_, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerId)
if err != nil {
l.Errorw("[PushOnlineUsers] FindOne error", logger.Field("error", err))
return fmt.Errorf("server not found: %w", err)
}
userOnlineIp := make([]cache.NodeOnlineUser, 0)
onlineUsers := make(node.OnlineUserSubscribe)
for _, user := range req.Users {
userOnlineIp = append(userOnlineIp, cache.NodeOnlineUser{
SID: user.SID,
IP: user.IP,
})
if online, ok := onlineUsers[user.SID]; ok {
// If user already exists, update IP if different
online = append(online, user.IP)
onlineUsers[user.SID] = online
} else {
// New user, add to map
onlineUsers[user.SID] = []string{user.IP}
}
}
err = l.svcCtx.NodeCache.AddOnlineUserIP(l.ctx, userOnlineIp)
err = l.svcCtx.NodeModel.UpdateOnlineUserSubscribe(l.ctx, req.ServerId, req.Protocol, onlineUsers)
if err != nil {
l.Errorw("[PushOnlineUsers] cache operation error", logger.Field("error", err))
return err
}
err = l.svcCtx.NodeCache.UpdateNodeOnlineUser(l.ctx, req.ServerId, userOnlineIp)
err = l.svcCtx.NodeModel.UpdateOnlineUserSubscribeGlobal(l.ctx, onlineUsers)
if err != nil {
l.Errorw("[PushOnlineUsers] cache operation error", logger.Field("error", err))
@@ -0,0 +1,93 @@
package server
import (
"context"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/tool"
)
type QueryServerProtocolConfigLogic struct {
logger.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// NewQueryServerProtocolConfigLogic Get Server Protocol Config
func NewQueryServerProtocolConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryServerProtocolConfigLogic {
return &QueryServerProtocolConfigLogic{
Logger: logger.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QueryServerProtocolConfigLogic) QueryServerProtocolConfig(req *types.QueryServerConfigRequest) (resp *types.QueryServerConfigResponse, err error) {
// find server
data, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerID)
if err != nil {
l.Errorf("[GetServerProtocols] FindOneServer Error: %s", err.Error())
return nil, err
}
// handler protocols
var protocols []types.Protocol
dst, err := data.UnmarshalProtocols()
if err != nil {
l.Errorf("[FilterServerList] UnmarshalProtocols Error: %s", err.Error())
return nil, err
}
tool.DeepCopy(&protocols, dst)
// filter by req.Protocols
if len(req.Protocols) > 0 {
var filtered []types.Protocol
protocolSet := make(map[string]struct{})
for _, p := range req.Protocols {
protocolSet[p] = struct{}{}
}
for _, p := range protocols {
if _, exists := protocolSet[p.Type]; exists {
filtered = append(filtered, p)
}
}
protocols = filtered
}
var dns []types.NodeDNS
if len(l.svcCtx.Config.Node.DNS) > 0 {
for _, d := range l.svcCtx.Config.Node.DNS {
dns = append(dns, types.NodeDNS{
Proto: d.Proto,
Address: d.Address,
Domains: d.Domains,
})
}
}
var outbound []types.NodeOutbound
if len(l.svcCtx.Config.Node.Outbound) > 0 {
for _, o := range l.svcCtx.Config.Node.Outbound {
outbound = append(outbound, types.NodeOutbound{
Name: o.Name,
Protocol: o.Protocol,
Address: o.Address,
Port: o.Port,
Password: o.Password,
Rules: o.Rules,
})
}
}
return &types.QueryServerConfigResponse{
TrafficReportThreshold: l.svcCtx.Config.Node.TrafficReportThreshold,
IPStrategy: l.svcCtx.Config.Node.IPStrategy,
DNS: dns,
Block: l.svcCtx.Config.Node.Block,
Outbound: outbound,
Protocols: protocols,
Total: int64(len(protocols)),
}, nil
}
+17 -7
View File
@@ -3,11 +3,12 @@ package server
import (
"context"
"errors"
"time"
"github.com/perfect-panel/ppanel-server/internal/model/cache"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/server/internal/model/node"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
)
type ServerPushStatusLogic struct {
@@ -16,7 +17,7 @@ type ServerPushStatusLogic struct {
svcCtx *svc.ServiceContext
}
// Push server status
// NewServerPushStatusLogic Push server status
func NewServerPushStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ServerPushStatusLogic {
return &ServerPushStatusLogic{
Logger: logger.WithContext(ctx),
@@ -27,12 +28,12 @@ func NewServerPushStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
func (l *ServerPushStatusLogic) ServerPushStatus(req *types.ServerPushStatusRequest) error {
// Find server info
serverInfo, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.ServerId)
serverInfo, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerId)
if err != nil || serverInfo.Id <= 0 {
l.Errorw("[PushOnlineUsers] FindOne error", logger.Field("error", err))
return errors.New("server not found")
}
err = l.svcCtx.NodeCache.UpdateNodeStatus(l.ctx, req.ServerId, cache.NodeStatus{
err = l.svcCtx.NodeModel.UpdateStatusCache(l.ctx, req.ServerId, &node.Status{
Cpu: req.Cpu,
Mem: req.Mem,
Disk: req.Disk,
@@ -42,5 +43,14 @@ func (l *ServerPushStatusLogic) ServerPushStatus(req *types.ServerPushStatusRequ
l.Errorw("[ServerPushStatus] UpdateNodeStatus error", logger.Field("error", err))
return errors.New("update node status failed")
}
now := time.Now()
serverInfo.LastReportedAt = &now
err = l.svcCtx.NodeModel.UpdateServer(l.ctx, serverInfo)
if err != nil {
l.Errorw("[ServerPushStatus] UpdateServer error", logger.Field("error", err))
return nil
}
return nil
}
@@ -3,14 +3,14 @@ package server
import (
"context"
"encoding/json"
"time"
"github.com/hibiken/asynq"
"github.com/perfect-panel/ppanel-server/internal/model/cache"
"github.com/perfect-panel/ppanel-server/internal/svc"
"github.com/perfect-panel/ppanel-server/internal/types"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/tool"
task "github.com/perfect-panel/ppanel-server/queue/types"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/tool"
task "github.com/perfect-panel/server/queue/types"
"github.com/pkg/errors"
)
@@ -32,7 +32,7 @@ func NewServerPushUserTrafficLogic(ctx context.Context, svcCtx *svc.ServiceConte
func (l *ServerPushUserTrafficLogic) ServerPushUserTraffic(req *types.ServerPushUserTrafficRequest) error {
// Find server info
serverInfo, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.ServerId)
serverInfo, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerId)
if err != nil {
l.Errorw("[PushOnlineUsers] FindOne error", logger.Field("error", err))
return errors.New("server not found")
@@ -40,23 +40,10 @@ func (l *ServerPushUserTrafficLogic) ServerPushUserTraffic(req *types.ServerPush
// Create traffic task
var request task.TrafficStatistics
var userTraffic []cache.UserTraffic
request.ServerId = serverInfo.Id
request.Protocol = req.Protocol
tool.DeepCopy(&request.Logs, req.Traffic)
tool.DeepCopy(&userTraffic, req.Traffic)
// update today traffic rank
err = l.svcCtx.NodeCache.AddNodeTodayTraffic(l.ctx, serverInfo.Id, userTraffic)
if err != nil {
l.Errorw("[ServerPushUserTraffic] AddNodeTodayTraffic error", logger.Field("error", err))
return errors.New("add node today traffic error")
}
for _, user := range req.Traffic {
if err = l.svcCtx.NodeCache.AddUserTodayTraffic(l.ctx, user.SID, user.Upload, user.Download); err != nil {
l.Errorw("[ServerPushUserTraffic] AddUserTodayTraffic error", logger.Field("error", err))
continue
}
}
// Push traffic task
val, _ := json.Marshal(request)
t := asynq.NewTask(task.ForthwithTrafficStatistics, val, asynq.MaxRetry(3))
@@ -66,5 +53,15 @@ func (l *ServerPushUserTrafficLogic) ServerPushUserTraffic(req *types.ServerPush
} else {
l.Infow("[ServerPushUserTraffic] Push traffic task success", logger.Field("task", t), logger.Field("info", info))
}
// Update server last reported time
now := time.Now()
serverInfo.LastReportedAt = &now
err = l.svcCtx.NodeModel.UpdateServer(l.ctx, serverInfo)
if err != nil {
l.Errorw("[ServerPushUserTraffic] UpdateServer error", logger.Field("error", err))
return nil
}
return nil
}