mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-10 14:46:08 +00:00
feat(sub): per-client external links and remote subscriptions
Add a Links tab to the client form for attaching third-party share links and remote subscription URLs per client. They are merged into the client's raw/JSON/Clash subscription output: links are emitted verbatim and parsed for JSON/Clash; subscription URLs are fetched (cached, with a short timeout) and their configs merged in. i18n keys added across all 13 locales.
This commit is contained in:
@@ -59,6 +59,7 @@ func (a *ClientController) initRouter(g *gin.RouterGroup) {
|
||||
g.POST("/del/:email", a.delete)
|
||||
g.POST("/:email/attach", a.attach)
|
||||
g.POST("/:email/detach", a.detach)
|
||||
g.POST("/:email/externalLinks", a.setExternalLinks)
|
||||
g.POST("/resetAllTraffics", a.resetAllTraffics)
|
||||
g.POST("/delDepleted", a.delDepleted)
|
||||
g.POST("/bulkAdjust", a.bulkAdjust)
|
||||
@@ -112,6 +113,11 @@ func (a *ClientController) get(c *gin.Context) {
|
||||
jsonMsg(c, I18nWeb(c, "get"), err)
|
||||
return
|
||||
}
|
||||
externalLinks, err := a.clientService.GetExternalLinksForRecord(rec.Id)
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "get"), err)
|
||||
return
|
||||
}
|
||||
flow, err := a.clientService.EffectiveFlow(nil, rec.Id)
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "get"), err)
|
||||
@@ -125,7 +131,7 @@ func (a *ClientController) get(c *gin.Context) {
|
||||
if t, tErr := a.inboundService.GetClientTrafficByEmail(email); tErr == nil && t != nil {
|
||||
usedTraffic = t.Up + t.Down
|
||||
}
|
||||
jsonObj(c, gin.H{"client": rec, "inboundIds": inboundIds, "usedTraffic": usedTraffic}, nil)
|
||||
jsonObj(c, gin.H{"client": rec, "inboundIds": inboundIds, "externalLinks": externalLinks, "usedTraffic": usedTraffic}, nil)
|
||||
}
|
||||
|
||||
func (a *ClientController) create(c *gin.Context) {
|
||||
@@ -185,6 +191,10 @@ type attachDetachBody struct {
|
||||
InboundIds []int `json:"inboundIds"`
|
||||
}
|
||||
|
||||
type externalLinksBody struct {
|
||||
ExternalLinks []service.ExternalLinkInput `json:"externalLinks"`
|
||||
}
|
||||
|
||||
func (a *ClientController) attach(c *gin.Context) {
|
||||
email := c.Param("email")
|
||||
var body attachDetachBody
|
||||
@@ -204,6 +214,21 @@ func (a *ClientController) attach(c *gin.Context) {
|
||||
notifyClientsChanged()
|
||||
}
|
||||
|
||||
func (a *ClientController) setExternalLinks(c *gin.Context) {
|
||||
email := c.Param("email")
|
||||
var body externalLinksBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err)
|
||||
return
|
||||
}
|
||||
if err := a.clientService.SetExternalLinksByEmail(email, body.ExternalLinks); err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err)
|
||||
return
|
||||
}
|
||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.inboundClientUpdateSuccess"), nil)
|
||||
notifyClientsChanged()
|
||||
}
|
||||
|
||||
func (a *ClientController) resetAllTraffics(c *gin.Context) {
|
||||
needRestart, err := a.clientService.ResetAllTraffics()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user