diff --git a/web/assets/css/custom.css b/web/assets/css/custom.css index aace5c28..3533806e 100644 --- a/web/assets/css/custom.css +++ b/web/assets/css/custom.css @@ -180,6 +180,7 @@ .ant-card-dark:hover { border-color: #e8e8e8; + box-shadow: 0 2px 8px rgba(255,255,255,.15); } .ant-card-dark .ant-table-thead th { @@ -222,20 +223,25 @@ .ant-card-dark .ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td, .ant-card-dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled), -.ant-card-dark .ant-calendar-date:hover { +.ant-card-dark .ant-calendar-date:hover, +.ant-card-dark .ant-select-dropdown-menu-item-active, +.ant-card-dark li.ant-calendar-time-picker-select-option-selected { background-color: #004488; } -.ant-card-dark tbody .ant-table-expanded-row { +.ant-card-dark tbody .ant-table-expanded-row, +.ant-card-dark .ant-calendar-time-picker-inner { color: hsla(0,0%,100%,.65); background-color: #1a212a; } .ant-card-dark .ant-input, .ant-card-dark .ant-input-number, +.ant-card-dark .ant-input-number-handler-wrap, .ant-card-dark .ant-calendar-input, .ant-card-dark .ant-select-dropdown-menu-item-selected, -.ant-card-dark .ant-select-selection { +.ant-card-dark .ant-select-selection, +.ant-card-dark .ant-calendar-picker-clear { color: hsla(0,0%,100%,.65); background-color: #2e3b52; } @@ -245,6 +251,12 @@ background-color: #161b22; } +.ant-dropdown-menu-dark, +.ant-card-dark .ant-modal-content { + border: 1px solid rgba(255, 255, 255, 0.65); + box-shadow: 0 2px 8px rgba(255,255,255,.15); +} + .ant-card-dark .ant-modal-content, .ant-card-dark .ant-modal-body, .ant-card-dark .ant-modal-header, @@ -286,6 +298,12 @@ border: 1px solid hsla(0,0%,100%,.30); } +.ant-card-dark .ant-tag { + color: hsla(0,0%,100%,.65); + background: rgba(255,255,255,.04); + border-color: #434343; +} + .ant-card-dark .ant-tag-blue { color: #3c9ae8; background: #111d2c; @@ -340,6 +358,29 @@ color: hsla(0,0%,100%,.65); background-color: #073763; border-color: #1890ff; - text-shadow: 0 -1px 0 rgba(0,0,0,.12); - box-shadow: 0 2px 0 rgba(0,0,0,.045); + text-shadow: 0 -1px 0 rgba(255,255,255,.12); + box-shadow: 0 2px 0 rgba(255,255,255,.045); +} +.ant-card-dark .ant-btn-primary:hover { + background-color: #40a9ff; + border-color: #40a9ff; +} + +.ant-dark .ant-popover-content { + border: 1px solid #e8e8e8; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(255,255,255,.15); +} + +.ant-dark .ant-popover-inner { + background: #222a37; +} + +.ant-dark .ant-popover-title, +.ant-dark .ant-popover-inner-content { + color: hsla(0,0%,100%,.65); +} + +.ant-dark .ant-popover-placement-top>.ant-popover-content>.ant-popover-arrow { + border-color: transparent #2e3b52 #2e3b52 transparent; } \ No newline at end of file diff --git a/web/assets/favicon.ico b/web/assets/favicon.ico new file mode 100644 index 00000000..75c00ca7 Binary files /dev/null and b/web/assets/favicon.ico differ diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js index ab6631a6..45980764 100644 --- a/web/assets/js/model/models.js +++ b/web/assets/js/model/models.js @@ -170,13 +170,13 @@ class AllSetting { this.webCertFile = ""; this.webKeyFile = ""; this.webBasePath = "/"; + this.expireDiff = ""; + this.trafficDiff = ""; this.tgBotEnable = false; this.tgBotToken = ""; this.tgBotChatId = ""; this.tgRunTime = "@daily"; this.tgBotBackup = false; - this.tgExpireDiff = ""; - this.tgTrafficDiff = ""; this.tgCpu = ""; this.xrayTemplateConfig = ""; diff --git a/web/controller/server.go b/web/controller/server.go index 7b7239d5..43a1fadc 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -38,7 +38,7 @@ func (a *ServerController) initRouter(g *gin.RouterGroup) { g.POST("/stopXrayService", a.stopXrayService) g.POST("/restartXrayService", a.restartXrayService) g.POST("/installXray/:version", a.installXray) - g.POST("/logs", a.getLogs) + g.POST("/logs/:count", a.getLogs) } func (a *ServerController) refreshStatus() { @@ -109,7 +109,8 @@ func (a *ServerController) restartXrayService(c *gin.Context) { } func (a *ServerController) getLogs(c *gin.Context) { - logs, err := a.serverService.GetLogs() + count := c.Param("count") + logs, err := a.serverService.GetLogs(count) if err != nil { jsonMsg(c, I18n(c, "getLogs"), err) return diff --git a/web/controller/setting.go b/web/controller/setting.go index 0456bca3..cfdfe5d6 100644 --- a/web/controller/setting.go +++ b/web/controller/setting.go @@ -33,6 +33,7 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) { g = g.Group("/setting") g.POST("/all", a.getAllSetting) + g.POST("/thresholds", a.getThresholds) g.POST("/update", a.updateSetting) g.POST("/updateUser", a.updateUser) g.POST("/restartPanel", a.restartPanel) @@ -47,6 +48,24 @@ func (a *SettingController) getAllSetting(c *gin.Context) { jsonObj(c, allSetting, nil) } +func (a *SettingController) getThresholds(c *gin.Context) { + expireDiff, err := a.settingService.GetExpireDiff() + if err != nil { + jsonMsg(c, I18n(c, "pages.setting.toasts.getSetting"), err) + return + } + trafficDiff, err := a.settingService.GetTrafficDiff() + if err != nil { + jsonMsg(c, I18n(c, "pages.setting.toasts.getSetting"), err) + return + } + result := map[string]interface{}{ + "expireDiff": expireDiff, + "trafficDiff": trafficDiff, + } + jsonObj(c, result, nil) +} + func (a *SettingController) updateSetting(c *gin.Context) { allSetting := &entity.AllSetting{} err := c.ShouldBind(allSetting) diff --git a/web/entity/entity.go b/web/entity/entity.go index 372f5caa..b464de00 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -32,13 +32,13 @@ type AllSetting struct { WebCertFile string `json:"webCertFile" form:"webCertFile"` WebKeyFile string `json:"webKeyFile" form:"webKeyFile"` WebBasePath string `json:"webBasePath" form:"webBasePath"` + ExpireDiff int `json:"expireDiff" form:"expireDiff"` + TrafficDiff int `json:"trafficDiff" form:"trafficDiff"` TgBotEnable bool `json:"tgBotEnable" form:"tgBotEnable"` TgBotToken string `json:"tgBotToken" form:"tgBotToken"` TgBotChatId string `json:"tgBotChatId" form:"tgBotChatId"` TgRunTime string `json:"tgRunTime" form:"tgRunTime"` TgBotBackup bool `json:"tgBotBackup" form:"tgBotBackup"` - TgExpireDiff int `json:"tgExpireDiff" form:"tgExpireDiff"` - TgTrafficDiff int `json:"tgTrafficDiff" form:"tgTrafficDiff"` TgCpu int `json:"tgCpu" form:"tgCpu"` XrayTemplateConfig string `json:"xrayTemplateConfig" form:"xrayTemplateConfig"` TimeLocation string `json:"timeLocation" form:"timeLocation"` diff --git a/web/html/xui/client_bulk_modal.html b/web/html/xui/client_bulk_modal.html index 7a03505e..6ac1ec70 100644 --- a/web/html/xui/client_bulk_modal.html +++ b/web/html/xui/client_bulk_modal.html @@ -10,8 +10,7 @@ Random+Prefix Random+Prefix+Num Random+Prefix+Num+Postfix - Random+Prefix+Num@Telegram Username - Prefix+Num+Postfix [ BE CAREFUL! ] + Prefix+Num+Postfix [ BE CAREFUL! ]
@@ -27,15 +26,19 @@ - tg_uname - {{ i18n "pages.client.postfix" }} + {{ i18n "pages.client.postfix" }} - {{ i18n "pages.client.clientCount" }} + + + + + + {{ i18n "pages.inbounds.totalFlow" }}(GB) @@ -83,6 +86,8 @@ lastNum: 1, emailPrefix: "", emailPostfix: "", + subId: "", + tgId: "", ok() { method=clientsBulkModal.emailMethod; if(method>1){ @@ -94,11 +99,13 @@ } prefix = (method>0 && clientsBulkModal.emailPrefix.length>0) ? clientsBulkModal.emailPrefix : ""; useNum=(method>1); - postfix = (method>2 && clientsBulkModal.emailPostfix.length>0) ? (method == 4 ? "@" : "") + clientsBulkModal.emailPostfix : ""; + postfix = (method>2 && clientsBulkModal.emailPostfix.length>0) ? clientsBulkModal.emailPostfix : ""; for (let i = start; i < end; i++) { newClient = clientsBulkModal.newClient(clientsBulkModal.dbInbound.protocol); - if(method==5) newClient.email = ""; + if(method==4) newClient.email = ""; newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix; + newClient.subId = clientsBulkModal.subId; + newClient.tgId = clientsBulkModal.tgId; newClient._totalGB = clientsBulkModal.totalGB; newClient._expiryTime = clientsBulkModal.expiryTime; clientsBulkModal.clients.push(newClient); @@ -118,7 +125,8 @@ this.lastNum= 1; this.emailPrefix= ""; this.emailPostfix= ""; - + this.subId= ""; + this.tgId= ""; this.dbInbound = new DBInbound(dbInbound); this.inbound = dbInbound.toInbound(); this.clients = this.getClients(this.inbound.protocol, this.inbound.settings); diff --git a/web/html/xui/form/client.html b/web/html/xui/form/client.html index 6b1b0f8f..1dac8165 100644 --- a/web/html/xui/form/client.html +++ b/web/html/xui/form/client.html @@ -30,7 +30,7 @@ - + diff --git a/web/html/xui/inbound_client_table.html b/web/html/xui/inbound_client_table.html index e2abeb1b..024ded7c 100644 --- a/web/html/xui/inbound_client_table.html +++ b/web/html/xui/inbound_client_table.html @@ -26,7 +26,7 @@ {{ i18n "indefinite" }} - - {{ i18n "enabled" }} - {{ i18n "disabled" }} - + + + + + + + + + +
Subscription link[[ infoModal.subBase + infoModal.clientSettings.subId ]]
Telegram Username@[[ infoModal.clientSettings.tgId ]]
@@ -160,7 +178,6 @@