package handlers import ( "platform/web/auth" edge2 "platform/web/domains/edge" proxy2 "platform/web/domains/proxy" g "platform/web/globals" m "platform/web/models" q "platform/web/queries" s "platform/web/services" "github.com/gofiber/fiber/v2" "gorm.io/gen/field" "gorm.io/gorm/clause" ) type RegisterEdgeReq struct { Name string `json:"name" validate:"required"` Version int `json:"version" validate:"required"` ISP edge2.ISP `json:"isp"` Prov string `json:"prov"` City string `json:"city"` } type RegisterEdgeResp struct { Id int32 `json:"id"` Host string `json:"host"` } func OnlineEdge(c *fiber.Ctx) (err error) { // 验证请求参数 var req = new(RegisterEdgeReq) err = g.Validator.Validate(c, req) if err != nil { return err } // 挑选合适的转发服务 var fwd *m.Proxy fwd, err = q.Proxy. LeftJoin(q.Edge, q.Edge.ProxyID.EqCol(q.Proxy.ID), q.Edge.Status.Eq(1)). Select(q.Proxy.ALL, q.Edge.ALL.Count().As("count")). Where(q.Proxy.Type.Eq(int32(proxy2.TypeSelfHosted))). Group(q.Proxy.ID). Order(field.NewField("", "count").Desc()). First() if err != nil { return err } // 保存节点信息 var edge = &m.Edge{ Name: req.Name, Version: int32(req.Version), Host: c.Context().RemoteIP().String(), Isp: int32(req.ISP), Prov: req.Prov, City: req.City, ProxyID: fwd.ID, Type: int32(edge2.TypeSelfHosted), Status: 1, } err = q.Edge.Clauses(clause.OnConflict{ UpdateAll: true, Columns: []clause.Column{{Name: "name"}}, }).Create(edge) if err != nil { return err } // 返回服务地址 return c.JSON(RegisterEdgeResp{ Id: edge.ID, Host: fwd.Host, }) } type OfflineEdgeReq struct { Name string `json:"name" validate:"required"` } func OfflineEdge(c *fiber.Ctx) (err error) { // 验证请求参数 var req = new(OfflineEdgeReq) err = g.Validator.Validate(c, req) if err != nil { return err } // 下线转发服务 _, err = q.Edge. Where(q.Edge.Name.Eq(req.Name)). UpdateSimple(q.Edge.Status.Value(0)) if err != nil { return err } return c.SendStatus(fiber.StatusOK) } type AllEdgesAvailableReq struct { s.EdgeFilter Count int `json:"count"` } type AllEdgesAvailableRespItem struct { Ip string `json:"ip"` // 节点地址 Port int32 `json:"port"` // 代理服务端口 Isp string `json:"isp"` // 运营商 Prov string `json:"prov"` // 省份 City string `json:"city"` // 城市 Status int32 `json:"status"` // 节点状态:0-离线,1-正常 } func AllEdgesAvailable(c *fiber.Ctx) (err error) { // 检查权限 _, err = auth.NewProtect(c).Payload(auth.PayloadInternalServer).Do() if err != nil { return err } // 验证请求参数 var req = new(AllEdgesAvailableReq) err = g.Validator.Validate(c, req) if err != nil { return err } // 获取可用的转发服务 infos, err := s.Edge.AllEdges(req.Count, req.EdgeFilter) if err != nil { return err } // 返回结果 var edges = make([]AllEdgesAvailableRespItem, len(infos)) for i, info := range infos { edges[i] = AllEdgesAvailableRespItem{ Ip: info.Host, Port: info.ProxyPort, Isp: edge2.ISPToStr(edge2.ISP(info.Isp)), Prov: info.Prov, City: info.City, Status: info.Status, } } return c.JSON(edges) }