feat(api): add traffic log details filtering and enhance traffic log structures
This commit is contained in:
parent
ad4f3df74e
commit
9b3cdbbb4f
@ -105,6 +105,7 @@ type (
|
|||||||
Download int64 `json:"download"` // Download traffic in bytes
|
Download int64 `json:"download"` // Download traffic in bytes
|
||||||
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
||||||
Date string `json:"date"` // Date in YYYY-MM-DD format
|
Date string `json:"date"` // Date in YYYY-MM-DD format
|
||||||
|
Details bool `json:"details"` // Whether to show detailed traffic
|
||||||
}
|
}
|
||||||
FilterSubscribeTrafficRequest {
|
FilterSubscribeTrafficRequest {
|
||||||
FilterLogParams
|
FilterLogParams
|
||||||
@ -121,6 +122,7 @@ type (
|
|||||||
Download int64 `json:"download"` // Download traffic in bytes
|
Download int64 `json:"download"` // Download traffic in bytes
|
||||||
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
||||||
Date string `json:"date"` // Date in YYYY-MM-DD format
|
Date string `json:"date"` // Date in YYYY-MM-DD format
|
||||||
|
Details bool `json:"details"` // Whether to show detailed traffic
|
||||||
}
|
}
|
||||||
FilterServerTrafficLogRequest {
|
FilterServerTrafficLogRequest {
|
||||||
FilterLogParams
|
FilterLogParams
|
||||||
@ -164,6 +166,25 @@ type (
|
|||||||
Total int64 `json:"total"`
|
Total int64 `json:"total"`
|
||||||
List []GiftLog `json:"list"`
|
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"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
@ -219,5 +240,9 @@ service ppanel {
|
|||||||
@doc "Filter gift log"
|
@doc "Filter gift log"
|
||||||
@handler FilterGiftLog
|
@handler FilterGiftLog
|
||||||
get /gift/list (FilterGiftLogRequest) returns (FilterGiftLogResponse)
|
get /gift/list (FilterGiftLogRequest) returns (FilterGiftLogResponse)
|
||||||
|
|
||||||
|
@doc "Filter traffic log details"
|
||||||
|
@handler FilterTrafficLogDetails
|
||||||
|
get /traffic/details (FilterTrafficLogDetailsRequest) returns (FilterTrafficLogDetailsResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import (
|
|||||||
// Filter server traffic log
|
// Filter server traffic log
|
||||||
func FilterServerTrafficLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
func FilterServerTrafficLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
var req types.FilterSubscribeTrafficRequest
|
var req types.FilterServerTrafficLogRequest
|
||||||
_ = c.ShouldBind(&req)
|
_ = c.ShouldBind(&req)
|
||||||
validateErr := svcCtx.Validate(&req)
|
validateErr := svcCtx.Validate(&req)
|
||||||
if validateErr != nil {
|
if validateErr != nil {
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
package server_bak
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
"github.com/perfect-panel/server/internal/logic/admin/log"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get node detail
|
// Filter traffic log details
|
||||||
func GetNodeDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
func FilterTrafficLogDetailsHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
var req types.GetDetailRequest
|
var req types.FilterTrafficLogDetailsRequest
|
||||||
_ = 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 GetNodeDetailHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l := server_bak.NewGetNodeDetailLogic(c.Request.Context(), svcCtx)
|
l := log.NewFilterTrafficLogDetailsLogic(c.Request.Context(), svcCtx)
|
||||||
resp, err := l.GetNodeDetail(&req)
|
resp, err := l.FilterTrafficLogDetails(&req)
|
||||||
result.HttpResult(c, resp, err)
|
result.HttpResult(c, resp, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"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_bak.NewBatchDeleteNodeGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.BatchDeleteNodeGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Batch delete node
|
|
||||||
func BatchDeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.BatchDeleteNodeRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewBatchDeleteNodeLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.BatchDeleteNode(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create node group
|
|
||||||
func CreateNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CreateNodeGroupRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewCreateNodeGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.CreateNodeGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create node
|
|
||||||
func CreateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CreateNodeRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewCreateNodeLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.CreateNode(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreateRuleGroupHandler Create rule group
|
|
||||||
func CreateRuleGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.CreateRuleGroupRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewCreateRuleGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.CreateRuleGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Delete node group
|
|
||||||
func DeleteNodeGroupHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.DeleteNodeGroupRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewDeleteNodeGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.DeleteNodeGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Delete node
|
|
||||||
func DeleteNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.DeleteNodeRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewDeleteNodeLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.DeleteNode(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"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_bak.NewDeleteRuleGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.DeleteRuleGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get node group list
|
|
||||||
func GetNodeGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := server_bak.NewGetNodeGroupListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetNodeGroupList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get node list
|
|
||||||
func GetNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.GetNodeServerListRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewGetNodeListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetNodeList(&req)
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get node tag list
|
|
||||||
func GetNodeTagListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := server_bak.NewGetNodeTagListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetNodeTagList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get rule group list
|
|
||||||
func GetRuleGroupListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
|
|
||||||
l := server_bak.NewGetRuleGroupListLogic(c.Request.Context(), svcCtx)
|
|
||||||
resp, err := l.GetRuleGroupList()
|
|
||||||
result.HttpResult(c, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Node sort
|
|
||||||
func NodeSortHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.NodeSortRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewNodeSortLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.NodeSort(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"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_bak.NewUpdateNodeGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdateNodeGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/result"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update node
|
|
||||||
func UpdateNodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var req types.UpdateNodeRequest
|
|
||||||
_ = c.ShouldBind(&req)
|
|
||||||
validateErr := svcCtx.Validate(&req)
|
|
||||||
if validateErr != nil {
|
|
||||||
result.ParamErrorResult(c, validateErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l := server_bak.NewUpdateNodeLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdateNode(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/perfect-panel/server/internal/logic/admin/server_bak"
|
|
||||||
"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_bak.NewUpdateRuleGroupLogic(c.Request.Context(), svcCtx)
|
|
||||||
err := l.UpdateRuleGroup(&req)
|
|
||||||
result.HttpResult(c, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -224,6 +224,9 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
|
|
||||||
// Filter user subscribe traffic log
|
// Filter user subscribe traffic log
|
||||||
adminLogGroupRouter.GET("/subscribe/traffic/list", adminLog.FilterUserSubscribeTrafficLogHandler(serverCtx))
|
adminLogGroupRouter.GET("/subscribe/traffic/list", adminLog.FilterUserSubscribeTrafficLogHandler(serverCtx))
|
||||||
|
|
||||||
|
// Filter traffic log details
|
||||||
|
adminLogGroupRouter.GET("/traffic/details", adminLog.FilterTrafficLogDetailsHandler(serverCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
adminMarketingGroupRouter := router.Group("/v1/admin/marketing")
|
adminMarketingGroupRouter := router.Group("/v1/admin/marketing")
|
||||||
|
|||||||
@ -4,9 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/model/log"
|
||||||
|
"github.com/perfect-panel/server/internal/model/traffic"
|
||||||
"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/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilterServerTrafficLogLogic struct {
|
type FilterServerTrafficLogLogic struct {
|
||||||
@ -23,21 +27,124 @@ func NewFilterServerTrafficLogLogic(ctx context.Context, svcCtx *svc.ServiceCont
|
|||||||
svcCtx: svcCtx,
|
svcCtx: svcCtx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *FilterServerTrafficLogLogic) FilterServerTrafficLog(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
func (l *FilterServerTrafficLogLogic) FilterServerTrafficLog(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
||||||
today := time.Now().Format("2006-01-02")
|
today := time.Now().Format("2006-01-02")
|
||||||
if req.Date == "" || req.Date == today {
|
var list []types.ServerTrafficLog
|
||||||
return l.handlerToday(req)
|
var total int64
|
||||||
} else {
|
|
||||||
return l.handlerSpecify(req)
|
if req.Date == today || req.Date == "" {
|
||||||
|
now := time.Now()
|
||||||
|
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
|
||||||
|
end := start.Add(24 * time.Hour).Add(-time.Nanosecond)
|
||||||
|
|
||||||
|
var serverTraffic []log.ServerTraffic
|
||||||
|
err = l.svcCtx.DB.WithContext(l.ctx).
|
||||||
|
Model(&traffic.TrafficLog{}).
|
||||||
|
Select("server_id, SUM(download + upload) AS total, SUM(download) AS download, SUM(upload) AS upload").
|
||||||
|
Where("timestamp BETWEEN ? AND ?", start, end).
|
||||||
|
Group("server_id").
|
||||||
|
Order("id DESC").
|
||||||
|
Scan(&serverTraffic).Error
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterServerTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "today traffic query error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range serverTraffic {
|
||||||
|
list = append(list, types.ServerTrafficLog{
|
||||||
|
ServerId: v.ServerId,
|
||||||
|
Upload: v.Upload,
|
||||||
|
Download: v.Download,
|
||||||
|
Total: v.Total,
|
||||||
|
Date: today,
|
||||||
|
Details: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
todayTotal := len(list)
|
||||||
|
|
||||||
|
startIdx := (req.Page - 1) * req.Size
|
||||||
|
endIdx := startIdx + req.Size
|
||||||
|
|
||||||
|
if startIdx < todayTotal {
|
||||||
|
if endIdx > todayTotal {
|
||||||
|
endIdx = todayTotal
|
||||||
|
}
|
||||||
|
pageData := list[startIdx:endIdx]
|
||||||
|
return &types.FilterServerTrafficLogResponse{
|
||||||
|
List: pageData,
|
||||||
|
Total: int64(todayTotal),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
need := endIdx - todayTotal
|
||||||
|
historyPage := (need + req.Size - 1) / req.Size // 算出需要的历史页数
|
||||||
|
historyData, historyTotal, err := l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||||
|
Page: historyPage,
|
||||||
|
Size: need,
|
||||||
|
Type: log.TypeServerTraffic.Uint8(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterServerTrafficLog] Query History Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "history query error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range historyData {
|
||||||
|
var content log.ServerTraffic
|
||||||
|
if err = content.Unmarshal([]byte(item.Content)); err != nil {
|
||||||
|
l.Errorw("[FilterServerTrafficLog] Unmarshal Error", logger.Field("error", err.Error()), logger.Field("content", item.Content))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, types.ServerTrafficLog{
|
||||||
|
ServerId: item.ObjectID,
|
||||||
|
Upload: content.Upload,
|
||||||
|
Download: content.Download,
|
||||||
|
Total: content.Total,
|
||||||
|
Date: item.Date,
|
||||||
|
Details: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回最终分页数据
|
||||||
|
if endIdx > len(list) {
|
||||||
|
endIdx = len(list)
|
||||||
|
}
|
||||||
|
pageData := list[startIdx:endIdx]
|
||||||
|
|
||||||
|
return &types.FilterServerTrafficLogResponse{
|
||||||
|
List: pageData,
|
||||||
|
Total: int64(todayTotal) + historyTotal,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (l *FilterServerTrafficLogLogic) handlerToday(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
data, total, err := l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||||
|
Page: req.Page,
|
||||||
|
Size: req.Size,
|
||||||
|
Type: log.TypeServerTraffic.Uint8(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterServerTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "history query error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return
|
for _, item := range data {
|
||||||
}
|
var content log.ServerTraffic
|
||||||
|
if err = content.Unmarshal([]byte(item.Content)); err != nil {
|
||||||
|
l.Errorw("[FilterServerTrafficLog] Unmarshal Error", logger.Field("error", err.Error()), logger.Field("content", item.Content))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, types.ServerTrafficLog{
|
||||||
|
ServerId: item.ObjectID,
|
||||||
|
Upload: content.Upload,
|
||||||
|
Download: content.Download,
|
||||||
|
Total: content.Total,
|
||||||
|
Date: item.Date,
|
||||||
|
Details: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (l *FilterServerTrafficLogLogic) handlerSpecify(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
return &types.FilterServerTrafficLogResponse{
|
||||||
return
|
List: list,
|
||||||
|
Total: total,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
79
internal/logic/admin/log/filterTrafficLogDetailsLogic.go
Normal file
79
internal/logic/admin/log/filterTrafficLogDetailsLogic.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/model/traffic"
|
||||||
|
"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/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterTrafficLogDetailsLogic struct {
|
||||||
|
logger.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter traffic log details
|
||||||
|
func NewFilterTrafficLogDetailsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FilterTrafficLogDetailsLogic {
|
||||||
|
return &FilterTrafficLogDetailsLogic{
|
||||||
|
Logger: logger.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *FilterTrafficLogDetailsLogic) FilterTrafficLogDetails(req *types.FilterTrafficLogDetailsRequest) (resp *types.FilterTrafficLogDetailsResponse, err error) {
|
||||||
|
var start, end time.Time
|
||||||
|
if req.Date != "" {
|
||||||
|
day, err := time.ParseInLocation("2006-01-02", req.Date, time.Local)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterTrafficLogDetails] Date Parse Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), " date parse error: %s", err.Error())
|
||||||
|
}
|
||||||
|
start = day
|
||||||
|
end = day.Add(24*time.Hour - time.Nanosecond)
|
||||||
|
}
|
||||||
|
var data []*traffic.TrafficLog
|
||||||
|
tx := l.svcCtx.DB.WithContext(l.ctx).Model(&traffic.TrafficLog{})
|
||||||
|
if req.ServerId != 0 {
|
||||||
|
tx = tx.Where("server_id = ?", req.ServerId)
|
||||||
|
}
|
||||||
|
if !start.IsZero() && !end.IsZero() {
|
||||||
|
tx = tx.Where("timestamp BETWEEN ? AND ?", start, end)
|
||||||
|
}
|
||||||
|
if req.UserId != 0 {
|
||||||
|
tx = tx.Where("user_id = ?", req.UserId)
|
||||||
|
}
|
||||||
|
if req.SubscribeId != 0 {
|
||||||
|
tx = tx.Where("subscribe_id = ?", req.SubscribeId)
|
||||||
|
}
|
||||||
|
var total int64
|
||||||
|
err = tx.Count(&total).Limit(req.Size).Offset((req.Page - 1) * req.Size).Find(&data).Error
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterTrafficLogDetails] Query Database Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), " database query error: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var logs []types.TrafficLogDetails
|
||||||
|
for _, v := range data {
|
||||||
|
logs = append(logs, types.TrafficLogDetails{
|
||||||
|
Id: v.Id,
|
||||||
|
UserId: v.UserId,
|
||||||
|
ServerId: v.ServerId,
|
||||||
|
SubscribeId: v.SubscribeId,
|
||||||
|
Download: v.Download,
|
||||||
|
Upload: v.Upload,
|
||||||
|
Timestamp: v.Timestamp.UnixMilli(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.FilterTrafficLogDetailsResponse{
|
||||||
|
List: logs,
|
||||||
|
Total: total,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@ -2,10 +2,15 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/model/log"
|
||||||
|
"github.com/perfect-panel/server/internal/model/traffic"
|
||||||
"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/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilterUserSubscribeTrafficLogLogic struct {
|
type FilterUserSubscribeTrafficLogLogic struct {
|
||||||
@ -24,7 +29,125 @@ func NewFilterUserSubscribeTrafficLogLogic(ctx context.Context, svcCtx *svc.Serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *FilterUserSubscribeTrafficLogLogic) FilterUserSubscribeTrafficLog(req *types.FilterSubscribeTrafficRequest) (resp *types.FilterSubscribeTrafficResponse, err error) {
|
func (l *FilterUserSubscribeTrafficLogLogic) FilterUserSubscribeTrafficLog(req *types.FilterSubscribeTrafficRequest) (resp *types.FilterSubscribeTrafficResponse, err error) {
|
||||||
// todo: add your logic here and delete this line
|
today := time.Now().Format("2006-01-02")
|
||||||
|
var list []types.UserSubscribeTrafficLog
|
||||||
|
var total int64
|
||||||
|
|
||||||
return
|
if req.Date == today || req.Date == "" {
|
||||||
|
now := time.Now()
|
||||||
|
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
|
||||||
|
end := start.Add(24 * time.Hour).Add(-time.Nanosecond)
|
||||||
|
|
||||||
|
var userTraffic []types.UserSubscribeTrafficLog
|
||||||
|
err = l.svcCtx.DB.WithContext(l.ctx).
|
||||||
|
Model(&traffic.TrafficLog{}).
|
||||||
|
Select("user_id, subscribe_id, SUM(download + upload) AS total, SUM(download) AS download, SUM(upload) AS upload").
|
||||||
|
Where("timestamp BETWEEN ? AND ?", start, end).
|
||||||
|
Group("user_id, subscribe_id").
|
||||||
|
Order("id DESC").
|
||||||
|
Scan(&userTraffic).Error
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterUserSubscribeTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range userTraffic {
|
||||||
|
list = append(list, types.UserSubscribeTrafficLog{
|
||||||
|
UserId: v.UserId,
|
||||||
|
SubscribeId: v.SubscribeId,
|
||||||
|
Upload: v.Upload,
|
||||||
|
Download: v.Download,
|
||||||
|
Total: v.Total,
|
||||||
|
Date: today,
|
||||||
|
Details: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
todayTotal := len(list)
|
||||||
|
|
||||||
|
startIdx := (req.Page - 1) * req.Size
|
||||||
|
endIdx := startIdx + req.Size
|
||||||
|
if startIdx < todayTotal {
|
||||||
|
if endIdx > todayTotal {
|
||||||
|
endIdx = todayTotal
|
||||||
|
}
|
||||||
|
pageData := list[startIdx:endIdx]
|
||||||
|
return &types.FilterSubscribeTrafficResponse{
|
||||||
|
List: pageData,
|
||||||
|
Total: int64(todayTotal),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
need := endIdx - todayTotal
|
||||||
|
historyPage := (need + req.Size - 1) / req.Size // 算出需要的历史页数
|
||||||
|
historyData, historyTotal, err := l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||||
|
Page: historyPage,
|
||||||
|
Size: need,
|
||||||
|
Type: log.TypeSubscribeTraffic.Uint8(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterUserSubscribeTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "[FilterUserSubscribeTrafficLog] Query Database Error")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, datum := range historyData {
|
||||||
|
var item log.UserTraffic
|
||||||
|
err = item.Unmarshal([]byte(datum.Content))
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterUserSubscribeTrafficLog] Unmarshal Content Error", logger.Field("error", err.Error()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, types.UserSubscribeTrafficLog{
|
||||||
|
UserId: item.UserId,
|
||||||
|
SubscribeId: item.SubscribeId,
|
||||||
|
Upload: item.Upload,
|
||||||
|
Download: item.Download,
|
||||||
|
Total: item.Total,
|
||||||
|
Date: datum.Date,
|
||||||
|
Details: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 返回最终分页数据
|
||||||
|
if endIdx > len(list) {
|
||||||
|
endIdx = len(list)
|
||||||
|
}
|
||||||
|
pageData := list[startIdx:endIdx]
|
||||||
|
|
||||||
|
return &types.FilterSubscribeTrafficResponse{
|
||||||
|
List: pageData,
|
||||||
|
Total: int64(todayTotal) + historyTotal,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
var data []*log.SystemLog
|
||||||
|
data, total, err = l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||||
|
Page: req.Page,
|
||||||
|
Size: req.Size,
|
||||||
|
Type: log.TypeSubscribeTraffic.Uint8(),
|
||||||
|
Data: req.Date,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterUserSubscribeTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "[FilterUserSubscribeTrafficLog] Query Database Error")
|
||||||
|
}
|
||||||
|
for _, datum := range data {
|
||||||
|
var item log.UserTraffic
|
||||||
|
err = item.Unmarshal([]byte(datum.Content))
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[FilterUserSubscribeTrafficLog] Unmarshal Content Error", logger.Field("error", err.Error()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, types.UserSubscribeTrafficLog{
|
||||||
|
UserId: item.UserId,
|
||||||
|
SubscribeId: item.SubscribeId,
|
||||||
|
Upload: item.Upload,
|
||||||
|
Download: item.Download,
|
||||||
|
Total: item.Total,
|
||||||
|
Date: datum.Date,
|
||||||
|
Details: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return &types.FilterSubscribeTrafficResponse{
|
||||||
|
List: list,
|
||||||
|
Total: total,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BatchDeleteNodeGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBatchDeleteNodeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BatchDeleteNodeGroupLogic {
|
|
||||||
return &BatchDeleteNodeGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *BatchDeleteNodeGroupLogic) BatchDeleteNodeGroup(req *types.BatchDeleteNodeGroupRequest) error {
|
|
||||||
// Check if the group is empty
|
|
||||||
count, err := l.svcCtx.ServerModel.QueryServerCountByServerGroups(l.ctx, req.Ids)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[BatchDeleteNodeGroup] Query Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query server error: %v", err)
|
|
||||||
}
|
|
||||||
if count > 0 {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.NodeGroupNotEmpty), "group is not empty")
|
|
||||||
}
|
|
||||||
// Delete the group
|
|
||||||
err = l.svcCtx.ServerModel.BatchDeleteNodeGroup(l.ctx, req.Ids)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[BatchDeleteNodeGroup] Delete Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BatchDeleteNodeLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBatchDeleteNodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BatchDeleteNodeLogic {
|
|
||||||
return &BatchDeleteNodeLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *BatchDeleteNodeLogic) BatchDeleteNode(req *types.BatchDeleteNodeRequest) error {
|
|
||||||
err := l.svcCtx.DB.Transaction(func(db *gorm.DB) error {
|
|
||||||
for _, id := range req.Ids {
|
|
||||||
err := l.svcCtx.ServerModel.Delete(l.ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[BatchDeleteNode] Delete Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/server"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateNodeGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCreateNodeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateNodeGroupLogic {
|
|
||||||
return &CreateNodeGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CreateNodeGroupLogic) CreateNodeGroup(req *types.CreateNodeGroupRequest) error {
|
|
||||||
groupInfo := &server.Group{
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
}
|
|
||||||
err := l.svcCtx.ServerModel.InsertGroup(l.ctx, groupInfo)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/internal/model/server"
|
|
||||||
"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"
|
|
||||||
queue "github.com/perfect-panel/server/queue/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateNodeLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCreateNodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateNodeLogic {
|
|
||||||
return &CreateNodeLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *CreateNodeLogic) CreateNode(req *types.CreateNodeRequest) error {
|
|
||||||
config, err := json.Marshal(req.Config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var serverInfo server.Server
|
|
||||||
tool.DeepCopy(&serverInfo, req)
|
|
||||||
serverInfo.Config = string(config)
|
|
||||||
nodeRelay, err := json.Marshal(req.RelayNode)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateNode] Marshal RelayNode Error: ", logger.Field("error", err.Error()))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(req.Tags) > 0 {
|
|
||||||
serverInfo.Tags = strings.Join(req.Tags, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
serverInfo.LastReportedAt = time.UnixMicro(1218124800)
|
|
||||||
|
|
||||||
serverInfo.City = req.City
|
|
||||||
serverInfo.Country = req.Country
|
|
||||||
|
|
||||||
serverInfo.RelayNode = string(nodeRelay)
|
|
||||||
if req.Protocol == "vless" {
|
|
||||||
var cfg types.Vless
|
|
||||||
if err = json.Unmarshal(config, &cfg); err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "json.Unmarshal error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if cfg.Security == "reality" && cfg.SecurityConfig.RealityPublicKey == "" {
|
|
||||||
public, private, err := tool.Curve25519Genkey(false, "")
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "generate curve25519 key error")
|
|
||||||
}
|
|
||||||
cfg.SecurityConfig.RealityPublicKey = public
|
|
||||||
cfg.SecurityConfig.RealityPrivateKey = private
|
|
||||||
cfg.SecurityConfig.RealityShortId = tool.GenerateShortID(private)
|
|
||||||
}
|
|
||||||
if cfg.SecurityConfig.RealityServerAddr == "" {
|
|
||||||
cfg.SecurityConfig.RealityServerAddr = cfg.SecurityConfig.SNI
|
|
||||||
}
|
|
||||||
if cfg.SecurityConfig.RealityServerPort == 0 {
|
|
||||||
cfg.SecurityConfig.RealityServerPort = 443
|
|
||||||
}
|
|
||||||
config, _ = json.Marshal(cfg)
|
|
||||||
serverInfo.Config = string(config)
|
|
||||||
} else if req.Protocol == "shadowsocks" {
|
|
||||||
var cfg types.Shadowsocks
|
|
||||||
if err = json.Unmarshal(config, &cfg); err != nil {
|
|
||||||
l.Errorf("[CreateNode] Unmarshal Shadowsocks Config Error: %v", err.Error())
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "json.Unmarshal error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if strings.Contains(cfg.Method, "2022") {
|
|
||||||
var length int
|
|
||||||
switch cfg.Method {
|
|
||||||
case "2022-blake3-aes-128-gcm":
|
|
||||||
length = 16
|
|
||||||
default:
|
|
||||||
length = 32
|
|
||||||
}
|
|
||||||
if len(cfg.ServerKey) != length {
|
|
||||||
cfg.ServerKey = tool.GenerateCipher(cfg.ServerKey, length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config, _ = json.Marshal(cfg)
|
|
||||||
serverInfo.Config = string(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = l.svcCtx.ServerModel.Insert(l.ctx, &serverInfo)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[CreateNode] Insert Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create server error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.City == "" || req.Country == "" {
|
|
||||||
// Marshal the task payload
|
|
||||||
payload, err := json.Marshal(queue.GetNodeCountry{
|
|
||||||
Protocol: serverInfo.Protocol,
|
|
||||||
ServerAddr: serverInfo.ServerAddr,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeCountry]: Marshal Error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrap(xerr.NewErrCode(xerr.ERROR), "Failed to marshal task payload")
|
|
||||||
}
|
|
||||||
// Create a queue task
|
|
||||||
task := asynq.NewTask(queue.ForthwithGetCountry, payload)
|
|
||||||
// Enqueue the task
|
|
||||||
taskInfo, err := l.svcCtx.Queue.Enqueue(task)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeCountry]: Enqueue Error", logger.Field("error", err.Error()), logger.Field("payload", string(payload)))
|
|
||||||
return errors.Wrap(xerr.NewErrCode(xerr.ERROR), "Failed to enqueue task")
|
|
||||||
}
|
|
||||||
l.Infow("[GetNodeCountry]: Enqueue Success", logger.Field("taskID", taskInfo.ID), logger.Field("payload", string(payload)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/rules"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/server"
|
|
||||||
"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"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateRuleGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create rule group
|
|
||||||
func NewCreateRuleGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateRuleGroupLogic {
|
|
||||||
return &CreateRuleGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func parseAndValidateRules(ruleText, ruleName string) ([]string, error) {
|
|
||||||
var rs []string
|
|
||||||
ruleArr := strings.Split(ruleText, "\n")
|
|
||||||
if len(ruleArr) == 0 {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "rules is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range ruleArr {
|
|
||||||
r := rules.NewRule(s, ruleName)
|
|
||||||
if r == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := r.Validate(); err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
rs = append(rs, r.String())
|
|
||||||
}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
func (l *CreateRuleGroupLogic) CreateRuleGroup(req *types.CreateRuleGroupRequest) error {
|
|
||||||
rs, err := parseAndValidateRules(req.Rules, req.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
info := &server.RuleGroup{
|
|
||||||
Name: req.Name,
|
|
||||||
Icon: req.Icon,
|
|
||||||
Type: req.Type,
|
|
||||||
Tags: tool.StringSliceToString(req.Tags),
|
|
||||||
Rules: strings.Join(rs, "\n"),
|
|
||||||
Default: req.Default,
|
|
||||||
Enable: req.Enable,
|
|
||||||
}
|
|
||||||
err = l.svcCtx.ServerModel.InsertRuleGroup(l.ctx, info)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[CreateRuleGroup] Insert Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create server rule group error: %v", err)
|
|
||||||
}
|
|
||||||
if req.Default {
|
|
||||||
if err = l.svcCtx.ServerModel.SetDefaultRuleGroup(l.ctx, info.Id); err != nil {
|
|
||||||
l.Errorw("[CreateRuleGroup] Set Default Rule Group Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "set default rule group error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteNodeGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDeleteNodeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteNodeGroupLogic {
|
|
||||||
return &DeleteNodeGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DeleteNodeGroupLogic) DeleteNodeGroup(req *types.DeleteNodeGroupRequest) error {
|
|
||||||
// Check if the group is empty
|
|
||||||
count, err := l.svcCtx.ServerModel.QueryServerCountByServerGroups(l.ctx, []int64{req.Id})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[DeleteNodeGroup] Query Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query server error: %v", err)
|
|
||||||
}
|
|
||||||
if count > 0 {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.NodeGroupNotEmpty), "group is not empty")
|
|
||||||
}
|
|
||||||
// Delete the group
|
|
||||||
err = l.svcCtx.ServerModel.DeleteGroup(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[DeleteNodeGroup] Delete Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
|
|
||||||
"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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteNodeLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDeleteNodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteNodeLogic {
|
|
||||||
return &DeleteNodeLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DeleteNodeLogic) DeleteNode(req *types.DeleteNodeRequest) error {
|
|
||||||
err := l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
// Delete server
|
|
||||||
err := l.svcCtx.ServerModel.Delete(l.ctx, req.Id, tx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Delete server to subscribe
|
|
||||||
subs, err := l.svcCtx.SubscribeModel.QuerySubscribeIdsByServerIdAndServerGroupId(l.ctx, req.Id, 0)
|
|
||||||
if err != nil {
|
|
||||||
l.Logger.Errorf("[DeleteNode] QuerySubscribeIdsByServerIdAndServerGroupId error: %v", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sub := range subs {
|
|
||||||
servers := tool.StringToInt64Slice(sub.Server)
|
|
||||||
newServers := tool.RemoveElementBySlice(servers, req.Id)
|
|
||||||
sub.Server = tool.Int64SliceToString(newServers)
|
|
||||||
if err = l.svcCtx.SubscribeModel.Update(l.ctx, sub, tx); err != nil {
|
|
||||||
l.Logger.Errorf("[DeleteNode] UpdateSubscribe error: %v", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[DeleteNode] Delete Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete server error: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteRuleGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete rule group
|
|
||||||
func NewDeleteRuleGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteRuleGroupLogic {
|
|
||||||
return &DeleteRuleGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DeleteRuleGroupLogic) DeleteRuleGroup(req *types.DeleteRuleGroupRequest) error {
|
|
||||||
err := l.svcCtx.ServerModel.DeleteRuleGroup(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[DeleteRuleGroup] Delete Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete server rule group error: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"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"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetNodeDetailLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetNodeDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNodeDetailLogic {
|
|
||||||
return &GetNodeDetailLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetNodeDetailLogic) GetNodeDetail(req *types.GetDetailRequest) (resp *types.Server, err error) {
|
|
||||||
detail, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get server detail error: %v", err.Error())
|
|
||||||
}
|
|
||||||
resp = &types.Server{}
|
|
||||||
tool.DeepCopy(resp, detail)
|
|
||||||
var cfg map[string]interface{}
|
|
||||||
err = json.Unmarshal([]byte(detail.Config), &cfg)
|
|
||||||
if err != nil {
|
|
||||||
cfg = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
resp.Config = cfg
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetNodeGroupListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetNodeGroupListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNodeGroupListLogic {
|
|
||||||
return &GetNodeGroupListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetNodeGroupListLogic) GetNodeGroupList() (resp *types.GetNodeGroupListResponse, err error) {
|
|
||||||
nodeGroupList, err := l.svcCtx.ServerModel.QueryAllGroup(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), err.Error())
|
|
||||||
}
|
|
||||||
nodeGroups := make([]types.ServerGroup, 0)
|
|
||||||
tool.DeepCopy(&nodeGroups, nodeGroupList)
|
|
||||||
return &types.GetNodeGroupListResponse{
|
|
||||||
Total: int64(len(nodeGroups)),
|
|
||||||
List: nodeGroups,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/server"
|
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
|
|
||||||
"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"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetNodeListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetNodeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNodeListLogic {
|
|
||||||
return &GetNodeListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetNodeListLogic) GetNodeList(req *types.GetNodeServerListRequest) (resp *types.GetNodeServerListResponse, err error) {
|
|
||||||
tags := make([]string, 0)
|
|
||||||
if req.Tags != "" {
|
|
||||||
tags = strings.Split(req.Tags, ",")
|
|
||||||
}
|
|
||||||
total, list, err := l.svcCtx.ServerModel.FindServerListByFilter(l.ctx, &server.ServerFilter{
|
|
||||||
Page: req.Page,
|
|
||||||
Size: req.Size,
|
|
||||||
Search: req.Search,
|
|
||||||
Tags: tags,
|
|
||||||
Group: req.GroupId,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeList] Query Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), err.Error())
|
|
||||||
}
|
|
||||||
nodes := make([]types.Server, 0)
|
|
||||||
for _, v := range list {
|
|
||||||
node := types.Server{}
|
|
||||||
tool.DeepCopy(&node, v)
|
|
||||||
// default relay mode
|
|
||||||
if node.RelayMode == "" {
|
|
||||||
node.RelayMode = "none"
|
|
||||||
}
|
|
||||||
if len(v.Tags) > 0 {
|
|
||||||
if strings.Contains(v.Tags, ",") {
|
|
||||||
node.Tags = strings.Split(v.Tags, ",")
|
|
||||||
} else {
|
|
||||||
node.Tags = []string{v.Tags}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// parse config
|
|
||||||
var cfg map[string]interface{}
|
|
||||||
err = json.Unmarshal([]byte(v.Config), &cfg)
|
|
||||||
if err != nil {
|
|
||||||
cfg = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
node.Config = cfg
|
|
||||||
relayNode := make([]types.NodeRelay, 0)
|
|
||||||
err = json.Unmarshal([]byte(v.RelayNode), &relayNode)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeList] Unmarshal RelayNode Error: ", logger.Field("error", err.Error()), logger.Field("relayNode", v.RelayNode))
|
|
||||||
}
|
|
||||||
node.RelayNode = relayNode
|
|
||||||
var status types.NodeStatus
|
|
||||||
nodeStatus, err := l.svcCtx.NodeCache.GetNodeStatus(l.ctx, v.Id)
|
|
||||||
if err != nil {
|
|
||||||
// redis nil is not a Error
|
|
||||||
if !errors.Is(err, redis.Nil) {
|
|
||||||
l.Errorw("[GetNodeList] Get Node Status Error: ", logger.Field("error", err.Error()))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onlineUser, err := l.svcCtx.NodeCache.GetNodeOnlineUser(l.ctx, v.Id)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeList] Get Node Online User Error: ", logger.Field("error", err.Error()))
|
|
||||||
} else {
|
|
||||||
status.Online = onlineUser
|
|
||||||
}
|
|
||||||
status.Cpu = nodeStatus.Cpu
|
|
||||||
status.Mem = nodeStatus.Mem
|
|
||||||
status.Disk = nodeStatus.Disk
|
|
||||||
status.UpdatedAt = nodeStatus.UpdatedAt
|
|
||||||
}
|
|
||||||
node.Status = &status
|
|
||||||
nodes = append(nodes, node)
|
|
||||||
}
|
|
||||||
return &types.GetNodeServerListResponse{
|
|
||||||
Total: total,
|
|
||||||
List: nodes,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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 GetNodeTagListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get node tag list
|
|
||||||
func NewGetNodeTagListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNodeTagListLogic {
|
|
||||||
return &GetNodeTagListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetNodeTagListLogic) GetNodeTagList() (resp *types.GetNodeTagListResponse, err error) {
|
|
||||||
tags, err := l.svcCtx.ServerModel.FindServerTags(l.ctx)
|
|
||||||
return &types.GetNodeTagListResponse{
|
|
||||||
Tags: tool.RemoveDuplicateElements(tags...),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetRuleGroupListLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rule group list
|
|
||||||
func NewGetRuleGroupListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetRuleGroupListLogic {
|
|
||||||
return &GetRuleGroupListLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetRuleGroupListLogic) GetRuleGroupList() (resp *types.GetRuleGroupResponse, err error) {
|
|
||||||
nodeRuleGroupList, err := l.svcCtx.ServerModel.QueryAllRuleGroup(l.ctx)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetRuleGroupList] Query Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), err.Error())
|
|
||||||
}
|
|
||||||
nodeRuleGroups := make([]types.ServerRuleGroup, len(nodeRuleGroupList))
|
|
||||||
for i, v := range nodeRuleGroupList {
|
|
||||||
nodeRuleGroups[i] = types.ServerRuleGroup{
|
|
||||||
Id: v.Id,
|
|
||||||
Icon: v.Icon,
|
|
||||||
Name: v.Name,
|
|
||||||
Type: v.Type,
|
|
||||||
Tags: strings.Split(v.Tags, ","),
|
|
||||||
Rules: v.Rules,
|
|
||||||
Enable: v.Enable,
|
|
||||||
Default: v.Default,
|
|
||||||
CreatedAt: v.CreatedAt.UnixMilli(),
|
|
||||||
UpdatedAt: v.UpdatedAt.UnixMilli(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &types.GetRuleGroupResponse{
|
|
||||||
Total: int64(len(nodeRuleGroups)),
|
|
||||||
List: nodeRuleGroups,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/server"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type NodeSortLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node sort
|
|
||||||
func NewNodeSortLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NodeSortLogic {
|
|
||||||
return &NodeSortLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *NodeSortLogic) NodeSort(req *types.NodeSortRequest) error {
|
|
||||||
err := l.svcCtx.ServerModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
|
||||||
// find all servers id
|
|
||||||
var existingIDs []int64
|
|
||||||
db.Model(&server.Server{}).Select("id").Find(&existingIDs)
|
|
||||||
// check if the id is valid
|
|
||||||
validIDMap := make(map[int64]bool)
|
|
||||||
for _, id := range existingIDs {
|
|
||||||
validIDMap[id] = true
|
|
||||||
}
|
|
||||||
// check if the sort is valid
|
|
||||||
var validItems []types.SortItem
|
|
||||||
for _, item := range req.Sort {
|
|
||||||
if validIDMap[item.Id] {
|
|
||||||
validItems = append(validItems, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// query all servers
|
|
||||||
var servers []*server.Server
|
|
||||||
db.Model(&server.Server{}).Order("sort ASC").Find(&servers)
|
|
||||||
// create a map of the current sort
|
|
||||||
currentSortMap := make(map[int64]int64)
|
|
||||||
for _, item := range servers {
|
|
||||||
currentSortMap[item.Id] = item.Sort
|
|
||||||
}
|
|
||||||
|
|
||||||
// new sort map
|
|
||||||
newSortMap := make(map[int64]int64)
|
|
||||||
for _, item := range validItems {
|
|
||||||
newSortMap[item.Id] = item.Sort
|
|
||||||
}
|
|
||||||
|
|
||||||
var itemsToUpdate []types.SortItem
|
|
||||||
for _, item := range validItems {
|
|
||||||
if oldSort, exists := currentSortMap[item.Id]; exists && oldSort != item.Sort {
|
|
||||||
itemsToUpdate = append(itemsToUpdate, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, item := range itemsToUpdate {
|
|
||||||
s, err := l.svcCtx.ServerModel.FindOne(l.ctx, item.Id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Sort = item.Sort
|
|
||||||
if err := l.svcCtx.ServerModel.Update(l.ctx, s, db); err != nil {
|
|
||||||
l.Errorw("[NodeSort] Update Database Error: ", logger.Field("error", err.Error()), logger.Field("id", item.Id), logger.Field("sort", item.Sort))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[NodeSort] Update Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
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/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateNodeGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUpdateNodeGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateNodeGroupLogic {
|
|
||||||
return &UpdateNodeGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateNodeGroupLogic) UpdateNodeGroup(req *types.UpdateNodeGroupRequest) error {
|
|
||||||
// check server group exist
|
|
||||||
nodeGroup, err := l.svcCtx.ServerModel.FindOneGroup(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), err.Error())
|
|
||||||
}
|
|
||||||
nodeGroup.Name = req.Name
|
|
||||||
nodeGroup.Description = req.Description
|
|
||||||
err = l.svcCtx.ServerModel.UpdateGroup(l.ctx, nodeGroup)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,139 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
|
||||||
"github.com/perfect-panel/server/pkg/device"
|
|
||||||
queue "github.com/perfect-panel/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"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateNodeLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUpdateNodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateNodeLogic {
|
|
||||||
return &UpdateNodeLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateNodeLogic) UpdateNode(req *types.UpdateNodeRequest) error {
|
|
||||||
// Check server exist
|
|
||||||
nodeInfo, err := l.svcCtx.ServerModel.FindOne(l.ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find server error: %v", err)
|
|
||||||
}
|
|
||||||
tool.DeepCopy(nodeInfo, req, tool.CopyWithIgnoreEmpty(false))
|
|
||||||
config, err := json.Marshal(req.Config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeInfo.Config = string(config)
|
|
||||||
nodeRelay, err := json.Marshal(req.RelayNode)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateNode] Marshal RelayNode Error: ", logger.Field("error", err.Error()))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理Tags字段
|
|
||||||
switch {
|
|
||||||
case len(req.Tags) > 0:
|
|
||||||
// 有Tags,进行连接
|
|
||||||
nodeInfo.Tags = strings.Join(req.Tags, ",")
|
|
||||||
default:
|
|
||||||
// 空数组,清空Tags
|
|
||||||
nodeInfo.Tags = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeInfo.City = req.City
|
|
||||||
nodeInfo.Country = req.Country
|
|
||||||
|
|
||||||
nodeInfo.RelayNode = string(nodeRelay)
|
|
||||||
if req.Protocol == "vless" {
|
|
||||||
var cfg types.Vless
|
|
||||||
if err := json.Unmarshal(config, &cfg); err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "json.Unmarshal error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if cfg.Security == "reality" && cfg.SecurityConfig.RealityPublicKey == "" {
|
|
||||||
public, private, err := tool.Curve25519Genkey(false, "")
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "generate curve25519 key error")
|
|
||||||
}
|
|
||||||
cfg.SecurityConfig.RealityPublicKey = public
|
|
||||||
cfg.SecurityConfig.RealityPrivateKey = private
|
|
||||||
cfg.SecurityConfig.RealityShortId = tool.GenerateShortID(private)
|
|
||||||
}
|
|
||||||
if cfg.SecurityConfig.RealityServerAddr == "" {
|
|
||||||
cfg.SecurityConfig.RealityServerAddr = cfg.SecurityConfig.SNI
|
|
||||||
}
|
|
||||||
if cfg.SecurityConfig.RealityServerPort == 0 {
|
|
||||||
cfg.SecurityConfig.RealityServerPort = 443
|
|
||||||
}
|
|
||||||
config, _ = json.Marshal(cfg)
|
|
||||||
nodeInfo.Config = string(config)
|
|
||||||
} else if req.Protocol == "shadowsocks" {
|
|
||||||
var cfg types.Shadowsocks
|
|
||||||
if err = json.Unmarshal(config, &cfg); err != nil {
|
|
||||||
l.Errorf("[CreateNode] Unmarshal Shadowsocks Config Error: %v", err.Error())
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "json.Unmarshal error: %v", err.Error())
|
|
||||||
}
|
|
||||||
if strings.Contains(cfg.Method, "2022") {
|
|
||||||
var length int
|
|
||||||
switch cfg.Method {
|
|
||||||
case "2022-blake3-aes-128-gcm":
|
|
||||||
length = 16
|
|
||||||
default:
|
|
||||||
length = 32
|
|
||||||
}
|
|
||||||
if len(cfg.ServerKey) != length {
|
|
||||||
cfg.ServerKey = tool.GenerateCipher(cfg.ServerKey, length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config, _ = json.Marshal(cfg)
|
|
||||||
nodeInfo.Config = string(config)
|
|
||||||
}
|
|
||||||
err = l.svcCtx.ServerModel.Update(l.ctx, nodeInfo)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[UpdateNode] Update Database Error: ", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create server error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.City == "" || req.Country == "" {
|
|
||||||
// Marshal the task payload
|
|
||||||
payload, err := json.Marshal(queue.GetNodeCountry{
|
|
||||||
Protocol: nodeInfo.Protocol,
|
|
||||||
ServerAddr: nodeInfo.ServerAddr,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeCountry]: Marshal Error", logger.Field("error", err.Error()))
|
|
||||||
return errors.Wrap(xerr.NewErrCode(xerr.ERROR), "Failed to marshal task payload")
|
|
||||||
}
|
|
||||||
// Create a queue task
|
|
||||||
task := asynq.NewTask(queue.ForthwithGetCountry, payload)
|
|
||||||
// Enqueue the task
|
|
||||||
taskInfo, err := l.svcCtx.Queue.Enqueue(task)
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[GetNodeCountry]: Enqueue Error", logger.Field("error", err.Error()), logger.Field("payload", string(payload)))
|
|
||||||
return errors.Wrap(xerr.NewErrCode(xerr.ERROR), "Failed to enqueue task")
|
|
||||||
}
|
|
||||||
l.Infow("[GetNodeCountry]: Enqueue Success", logger.Field("taskID", taskInfo.ID), logger.Field("payload", string(payload)))
|
|
||||||
}
|
|
||||||
|
|
||||||
l.svcCtx.DeviceManager.Broadcast(device.SubscribeUpdate)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
package server_bak
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/tool"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/server"
|
|
||||||
"github.com/perfect-panel/server/pkg/xerr"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
|
||||||
"github.com/perfect-panel/server/internal/types"
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateRuleGroupLogic struct {
|
|
||||||
logger.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUpdateRuleGroupLogic Update rule group
|
|
||||||
func NewUpdateRuleGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateRuleGroupLogic {
|
|
||||||
return &UpdateRuleGroupLogic{
|
|
||||||
Logger: logger.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateRuleGroupLogic) UpdateRuleGroup(req *types.UpdateRuleGroupRequest) error {
|
|
||||||
rs, err := parseAndValidateRules(req.Rules, req.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = l.svcCtx.ServerModel.UpdateRuleGroup(l.ctx, &server.RuleGroup{
|
|
||||||
Id: req.Id,
|
|
||||||
Icon: req.Icon,
|
|
||||||
Type: req.Type,
|
|
||||||
Name: req.Name,
|
|
||||||
Tags: tool.StringSliceToString(req.Tags),
|
|
||||||
Rules: strings.Join(rs, "\n"),
|
|
||||||
Default: req.Default,
|
|
||||||
Enable: req.Enable,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), err.Error())
|
|
||||||
}
|
|
||||||
if req.Default {
|
|
||||||
if err = l.svcCtx.ServerModel.SetDefaultRuleGroup(l.ctx, req.Id); err != nil {
|
|
||||||
l.Errorf("SetDefaultRuleGroup error: %v", err.Error())
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -352,6 +352,7 @@ type ServerTraffic struct {
|
|||||||
ServerId int64 `json:"server_id"` // Server ID
|
ServerId int64 `json:"server_id"` // Server ID
|
||||||
Upload int64 `json:"upload"` // Upload traffic in bytes
|
Upload int64 `json:"upload"` // Upload traffic in bytes
|
||||||
Download int64 `json:"download"` // Download traffic in bytes
|
Download int64 `json:"download"` // Download traffic in bytes
|
||||||
|
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal implements the json.Marshaler interface for ServerTraffic.
|
// Marshal implements the json.Marshaler interface for ServerTraffic.
|
||||||
|
|||||||
@ -26,7 +26,7 @@ type customSystemLogLogicModel interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *customSystemLogModel) FilterSystemLog(ctx context.Context, filter *FilterParams) ([]*SystemLog, int64, error) {
|
func (m *customSystemLogModel) FilterSystemLog(ctx context.Context, filter *FilterParams) ([]*SystemLog, int64, error) {
|
||||||
tx := m.WithContext(ctx).Model(&SystemLog{})
|
tx := m.WithContext(ctx).Model(&SystemLog{}).Order("id DESC")
|
||||||
if filter == nil {
|
if filter == nil {
|
||||||
filter = &FilterParams{
|
filter = &FilterParams{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
|
|||||||
@ -674,6 +674,18 @@ type FilterSubscribeTrafficResponse struct {
|
|||||||
List []UserSubscribeTrafficLog `json:"list"`
|
List []UserSubscribeTrafficLog `json:"list"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FilterTrafficLogDetailsRequest struct {
|
||||||
|
FilterLogParams
|
||||||
|
ServerId int64 `form:"server_id,optional"`
|
||||||
|
SubscribeId int64 `form:"subscribe_id,optional"`
|
||||||
|
UserId int64 `form:"user_id,optional"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterTrafficLogDetailsResponse struct {
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
List []TrafficLogDetails `json:"list"`
|
||||||
|
}
|
||||||
|
|
||||||
type Follow struct {
|
type Follow struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
TicketId int64 `json:"ticket_id"`
|
TicketId int64 `json:"ticket_id"`
|
||||||
@ -1743,6 +1755,7 @@ type ServerTrafficLog struct {
|
|||||||
Download int64 `json:"download"` // Download traffic in bytes
|
Download int64 `json:"download"` // Download traffic in bytes
|
||||||
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
||||||
Date string `json:"date"` // Date in YYYY-MM-DD format
|
Date string `json:"date"` // Date in YYYY-MM-DD format
|
||||||
|
Details bool `json:"details"` // Whether to show detailed traffic
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerUser struct {
|
type ServerUser struct {
|
||||||
@ -1990,6 +2003,16 @@ type TrafficLog struct {
|
|||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TrafficLogDetails struct {
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
type TransportConfig struct {
|
type TransportConfig struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
@ -2384,6 +2407,7 @@ type UserSubscribeTrafficLog struct {
|
|||||||
Download int64 `json:"download"` // Download traffic in bytes
|
Download int64 `json:"download"` // Download traffic in bytes
|
||||||
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
||||||
Date string `json:"date"` // Date in YYYY-MM-DD format
|
Date string `json:"date"` // Date in YYYY-MM-DD format
|
||||||
|
Details bool `json:"details"` // Whether to show detailed traffic
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserTraffic struct {
|
type UserTraffic struct {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user