diff options
27 files changed, 1315 insertions, 493 deletions
@@ -1,15 +1,15 @@ .idea .vscode +.cache +.sync* +*.tar.gz +access.log +error.log tmp +main backup/ bin/ dist/ -x-ui-*.tar.gz -/x-ui -/release.sh -.sync* -main release/ -access.log -error.log -.cache +/release.sh +/x-ui @@ -194,6 +194,7 @@ Reference syntax: | `GET` | `"/list"` | Get all inbounds | | `GET` | `"/get/:id"` | Get inbound with inbound.id | | `GET` | `"/getClientTraffics/:email"` | Get Client Traffics with email | +| `GET` | `"/createbackup"` | Telegram bot sends backup to admins | | `POST` | `"/add"` | Add inbound | | `POST` | `"/del/:id"` | Delete Inbound | | `POST` | `"/update/:id"` | Update Inbound | diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js index a3fd2633..e1fb5d02 100644 --- a/web/assets/js/model/models.js +++ b/web/assets/js/model/models.js @@ -181,6 +181,7 @@ class AllSetting { this.tgRunTime = "@daily"; this.tgBotBackup = false; this.tgCpu = ""; + this.tgLang = ""; this.xrayTemplateConfig = ""; this.secretEnable = false; diff --git a/web/controller/api.go b/web/controller/api.go index 17073345..32c639f8 100644 --- a/web/controller/api.go +++ b/web/controller/api.go @@ -102,5 +102,5 @@ func (a *APIController) delDepletedClients(c *gin.Context) { } func (a *APIController) createBackup(c *gin.Context) { - a.Tgbot.SendBackUP(c) + a.Tgbot.SendBackupToAdmins() } diff --git a/web/controller/base.go b/web/controller/base.go index 98e1831c..674a195d 100644 --- a/web/controller/base.go +++ b/web/controller/base.go @@ -2,6 +2,8 @@ package controller import ( "net/http" + "x-ui/logger" + "x-ui/web/locale" "x-ui/web/session" "github.com/gin-gonic/gin" @@ -13,7 +15,7 @@ type BaseController struct { func (a *BaseController) checkLogin(c *gin.Context) { if !session.IsLogin(c) { if isAjax(c) { - pureJsonMsg(c, false, I18n(c, "pages.login.loginAgain")) + pureJsonMsg(c, false, I18nWeb(c, "pages.login.loginAgain")) } else { c.Redirect(http.StatusTemporaryRedirect, c.GetString("base_path")) } @@ -23,11 +25,13 @@ func (a *BaseController) checkLogin(c *gin.Context) { } } -func I18n(c *gin.Context, name string) string { - anyfunc, _ := c.Get("I18n") - i18n, _ := anyfunc.(func(key string, params ...string) (string, error)) - - message, _ := i18n(name) - - return message +func I18nWeb(c *gin.Context, name string, params ...string) string { + anyfunc, funcExists := c.Get("I18n") + if !funcExists { + logger.Warning("I18n function not exists in gin context!") + return "" + } + i18nFunc, _ := anyfunc.(func(i18nType locale.I18nType, key string, keyParams ...string) string) + msg := i18nFunc(locale.Web, name, params...) + return msg } diff --git a/web/controller/inbound.go b/web/controller/inbound.go index 8360cf62..d13e40bc 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -60,7 +60,7 @@ func (a *InboundController) getInbounds(c *gin.Context) { user := session.GetLoginUser(c) inbounds, err := a.inboundService.GetInbounds(user.Id) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.toasts.obtain"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.obtain"), err) return } jsonObj(c, inbounds, nil) @@ -68,12 +68,12 @@ func (a *InboundController) getInbounds(c *gin.Context) { func (a *InboundController) getInbound(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "get"), err) + jsonMsg(c, I18nWeb(c, "get"), err) return } inbound, err := a.inboundService.GetInbound(id) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.toasts.obtain"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.obtain"), err) return } jsonObj(c, inbound, nil) @@ -93,7 +93,7 @@ func (a *InboundController) addInbound(c *gin.Context) { inbound := &model.Inbound{} err := c.ShouldBind(inbound) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.create"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.create"), err) return } user := session.GetLoginUser(c) @@ -101,7 +101,7 @@ func (a *InboundController) addInbound(c *gin.Context) { inbound.Enable = true inbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port) inbound, err = a.inboundService.AddInbound(inbound) - jsonMsgObj(c, I18n(c, "pages.inbounds.create"), inbound, err) + jsonMsgObj(c, I18nWeb(c, "pages.inbounds.create"), inbound, err) if err == nil { a.xrayService.SetToNeedRestart() } @@ -110,11 +110,11 @@ func (a *InboundController) addInbound(c *gin.Context) { func (a *InboundController) delInbound(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "delete"), err) + jsonMsg(c, I18nWeb(c, "delete"), err) return } err = a.inboundService.DelInbound(id) - jsonMsgObj(c, I18n(c, "delete"), id, err) + jsonMsgObj(c, I18nWeb(c, "delete"), id, err) if err == nil { a.xrayService.SetToNeedRestart() } @@ -123,7 +123,7 @@ func (a *InboundController) delInbound(c *gin.Context) { func (a *InboundController) updateInbound(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } inbound := &model.Inbound{ @@ -131,11 +131,11 @@ func (a *InboundController) updateInbound(c *gin.Context) { } err = c.ShouldBind(inbound) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } inbound, err = a.inboundService.UpdateInbound(inbound) - jsonMsgObj(c, I18n(c, "pages.inbounds.update"), inbound, err) + jsonMsgObj(c, I18nWeb(c, "pages.inbounds.update"), inbound, err) if err == nil { a.xrayService.SetToNeedRestart() } @@ -165,7 +165,7 @@ func (a *InboundController) addInboundClient(c *gin.Context) { data := &model.Inbound{} err := c.ShouldBind(data) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } @@ -183,7 +183,7 @@ func (a *InboundController) addInboundClient(c *gin.Context) { func (a *InboundController) delInboundClient(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } clientId := c.Param("clientId") @@ -205,7 +205,7 @@ func (a *InboundController) updateInboundClient(c *gin.Context) { inbound := &model.Inbound{} err := c.ShouldBind(inbound) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } @@ -223,7 +223,7 @@ func (a *InboundController) updateInboundClient(c *gin.Context) { func (a *InboundController) resetClientTraffic(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } email := c.Param("email") @@ -251,7 +251,7 @@ func (a *InboundController) resetAllTraffics(c *gin.Context) { func (a *InboundController) resetAllClientTraffics(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } @@ -266,7 +266,7 @@ func (a *InboundController) resetAllClientTraffics(c *gin.Context) { func (a *InboundController) delDepletedClients(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { - jsonMsg(c, I18n(c, "pages.inbounds.update"), err) + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) return } err = a.inboundService.DelDepletedClients(id) diff --git a/web/controller/index.go b/web/controller/index.go index ac2ceca1..0254106c 100644 --- a/web/controller/index.go +++ b/web/controller/index.go @@ -49,26 +49,27 @@ func (a *IndexController) login(c *gin.Context) { var form LoginForm err := c.ShouldBind(&form) if err != nil { - pureJsonMsg(c, false, I18n(c, "pages.login.toasts.invalidFormData")) + pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.invalidFormData")) return } if form.Username == "" { - pureJsonMsg(c, false, I18n(c, "pages.login.toasts.emptyUsername")) + pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.emptyUsername")) return } if form.Password == "" { - pureJsonMsg(c, false, I18n(c, "pages.login.toasts.emptyPassword")) + pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.emptyPassword")) return } + user := a.userService.CheckUser(form.Username, form.Password, form.LoginSecret) timeStr := time.Now().Format("2006-01-02 15:04:05") if user == nil { - a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 0) logger.Infof("wrong username or password: \"%s\" \"%s\"", form.Username, form.Password) - pureJsonMsg(c, false, I18n(c, "pages.login.toasts.wrongUsernameOrPassword")) + a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 0) + pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.wrongUsernameOrPassword")) return } else { - logger.Infof("%s login success,Ip Address:%s\n", form.Username, getRemoteIp(c)) + logger.Infof("%s login success, Ip Address: %s\n", form.Username, getRemoteIp(c)) a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 1) } @@ -86,7 +87,7 @@ func (a *IndexController) login(c *gin.Context) { err = session.SetLoginUser(c, user) logger.Info("user", user.Id, "login success") - jsonMsg(c, I18n(c, "pages.login.toasts.successLogin"), err) + jsonMsg(c, I18nWeb(c, "pages.login.toasts.successLogin"), err) } func (a *IndexController) logout(c *gin.Context) { diff --git a/web/controller/server.go b/web/controller/server.go index 2db6e7fd..cc4eaacc 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -81,7 +81,7 @@ func (a *ServerController) getXrayVersion(c *gin.Context) { versions, err := a.serverService.GetXrayVersions() if err != nil { - jsonMsg(c, I18n(c, "getVersion"), err) + jsonMsg(c, I18nWeb(c, "getVersion"), err) return } @@ -94,7 +94,7 @@ func (a *ServerController) getXrayVersion(c *gin.Context) { func (a *ServerController) installXray(c *gin.Context) { version := c.Param("version") err := a.serverService.UpdateXray(version) - jsonMsg(c, I18n(c, "install")+" xray", err) + jsonMsg(c, I18nWeb(c, "install")+" xray", err) } func (a *ServerController) stopXrayService(c *gin.Context) { diff --git a/web/controller/setting.go b/web/controller/setting.go index 3aed69e6..226b7975 100644 --- a/web/controller/setting.go +++ b/web/controller/setting.go @@ -49,7 +49,7 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) { func (a *SettingController) getAllSetting(c *gin.Context) { allSetting, err := a.settingService.GetAllSetting() if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.getSettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } jsonObj(c, allSetting, nil) @@ -58,7 +58,7 @@ func (a *SettingController) getAllSetting(c *gin.Context) { func (a *SettingController) getDefaultJsonConfig(c *gin.Context) { defaultJsonConfig, err := a.settingService.GetDefaultJsonConfig() if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.getSettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } jsonObj(c, defaultJsonConfig, nil) @@ -67,22 +67,22 @@ func (a *SettingController) getDefaultJsonConfig(c *gin.Context) { func (a *SettingController) getDefaultSettings(c *gin.Context) { expireDiff, err := a.settingService.GetExpireDiff() if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.getSettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } trafficDiff, err := a.settingService.GetTrafficDiff() if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.getSettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } defaultCert, err := a.settingService.GetCertFile() if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.getSettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } defaultKey, err := a.settingService.GetKeyFile() if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.getSettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err) return } result := map[string]interface{}{ @@ -98,27 +98,27 @@ func (a *SettingController) updateSetting(c *gin.Context) { allSetting := &entity.AllSetting{} err := c.ShouldBind(allSetting) if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.modifySettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err) return } err = a.settingService.UpdateAllSetting(allSetting) - jsonMsg(c, I18n(c, "pages.settings.toasts.modifySettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err) } func (a *SettingController) updateUser(c *gin.Context) { form := &updateUserForm{} err := c.ShouldBind(form) if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.modifySettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err) return } user := session.GetLoginUser(c) if user.Username != form.OldUsername || user.Password != form.OldPassword { - jsonMsg(c, I18n(c, "pages.settings.toasts.modifyUser"), errors.New(I18n(c, "pages.settings.toasts.originalUserPassIncorrect"))) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), errors.New(I18nWeb(c, "pages.settings.toasts.originalUserPassIncorrect"))) return } if form.NewUsername == "" || form.NewPassword == "" { - jsonMsg(c, I18n(c, "pages.settings.toasts.modifyUser"), errors.New(I18n(c, "pages.settings.toasts.userPassMustBeNotEmpty"))) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), errors.New(I18nWeb(c, "pages.settings.toasts.userPassMustBeNotEmpty"))) return } err = a.userService.UpdateUser(user.Id, form.NewUsername, form.NewPassword) @@ -127,19 +127,19 @@ func (a *SettingController) updateUser(c *gin.Context) { user.Password = form.NewPassword session.SetLoginUser(c, user) } - jsonMsg(c, I18n(c, "pages.settings.toasts.modifyUser"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), err) } func (a *SettingController) restartPanel(c *gin.Context) { err := a.panelService.RestartPanel(time.Second * 3) - jsonMsg(c, I18n(c, "pages.settings.restartPanel"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.restartPanel"), err) } func (a *SettingController) updateSecret(c *gin.Context) { form := &updateSecretForm{} err := c.ShouldBind(form) if err != nil { - jsonMsg(c, I18n(c, "pages.settings.toasts.modifySettings"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err) } user := session.GetLoginUser(c) err = a.userService.UpdateUserSecret(user.Id, form.LoginSecret) @@ -147,7 +147,7 @@ func (a *SettingController) updateSecret(c *gin.Context) { user.LoginSecret = form.LoginSecret session.SetLoginUser(c, user) } - jsonMsg(c, I18n(c, "pages.settings.toasts.modifyUser"), err) + jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), err) } func (a *SettingController) getUserSecret(c *gin.Context) { diff --git a/web/controller/util.go b/web/controller/util.go index dc5c83b0..da77189b 100644 --- a/web/controller/util.go +++ b/web/controller/util.go @@ -38,12 +38,12 @@ func jsonMsgObj(c *gin.Context, msg string, obj interface{}, err error) { if err == nil { m.Success = true if msg != "" { - m.Msg = msg + I18n(c, "success") + m.Msg = msg + I18nWeb(c, "success") } } else { m.Success = false - m.Msg = msg + I18n(c, "fail") + ": " + err.Error() - logger.Warning(msg+I18n(c, "fail")+": ", err) + m.Msg = msg + I18nWeb(c, "fail") + ": " + err.Error() + logger.Warning(msg+I18nWeb(c, "fail")+": ", err) } c.JSON(http.StatusOK, m) } diff --git a/web/entity/entity.go b/web/entity/entity.go index b370b7ba..52f26769 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -41,6 +41,7 @@ type AllSetting struct { TgRunTime string `json:"tgRunTime" form:"tgRunTime"` TgBotBackup bool `json:"tgBotBackup" form:"tgBotBackup"` TgCpu int `json:"tgCpu" form:"tgCpu"` + TgLang string `json:"tgLang" form:"tgLang"` XrayTemplateConfig string `json:"xrayTemplateConfig" form:"xrayTemplateConfig"` TimeLocation string `json:"timeLocation" form:"timeLocation"` SecretEnable bool `json:"secretEnable" form:"secretEnable"` diff --git a/web/global/hashStorage.go b/web/global/hashStorage.go new file mode 100644 index 00000000..9dfea169 --- /dev/null +++ b/web/global/hashStorage.go @@ -0,0 +1,82 @@ +package global + +import ( + "crypto/md5" + "encoding/hex" + "regexp" + "sync" + "time" +) + +type HashEntry struct { + Hash string + Value string + Timestamp time.Time +} + +type HashStorage struct { + sync.RWMutex + Data map[string]HashEntry + Expiration time.Duration + +} + +func NewHashStorage(expiration time.Duration) *HashStorage { + return &HashStorage{ + Data: make(map[string]HashEntry), + Expiration: expiration, + } +} + +func (h *HashStorage) SaveHash(query string) string { + h.Lock() + defer h.Unlock() + + md5Hash := md5.Sum([]byte(query)) + md5HashString := hex.EncodeToString(md5Hash[:]) + + entry := HashEntry{ + Hash: md5HashString, + Value: query, + Timestamp: time.Now(), + } + + h.Data[md5HashString] = entry + + return md5HashString +} + + +func (h *HashStorage) GetValue(hash string) (string, bool) { + h.RLock() + defer h.RUnlock() + + entry, exists := h.Data[hash] + + return entry.Value, exists +} + +func (h *HashStorage) IsMD5(hash string) bool { + match, _ := regexp.MatchString("^[a-f0-9]{32}$", hash) + return match +} + +func (h *HashStorage) RemoveExpiredHashes() { + h.Lock() + defer h.Unlock() + + now := time.Now() + + for hash, entry := range h.Data { + if now.Sub(entry.Timestamp) > h.Expiration { + delete(h.Data, hash) + } + } +} + +func (h *HashStorage) Reset() { + h.Lock() + defer h.Unlock() + + h.Data = make(map[string]HashEntry) +} diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html index 91642727..35f101ca 100644 --- a/web/html/xui/form/tls_settings.html +++ b/web/html/xui/form/tls_settings.html @@ -10,7 +10,7 @@ Reality <a-tooltip> <template slot="title"> - <span>{{ i18n "pages.inbounds.realityDesc" }}</span> + <span>{{ i18n "pages.inbounds.realityDesc" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> @@ -22,7 +22,7 @@ XTLS <a-tooltip> <template slot="title"> - <span>{{ i18n "pages.inbounds.xtlsDesc" }}</span> + <span>{{ i18n "pages.inbounds.xtlsDesc" }}</span> </template> <a-icon type="question-circle" theme="filled"></a-icon> </a-tooltip> @@ -100,7 +100,7 @@ </a-form> <!-- xtls settings --> -<a-form v-if="inbound.xtls" layout="inline"> +<a-form v-else-if="inbound.xtls" layout="inline"> <a-form-item label='{{ i18n "domainName" }}'> <a-input v-model.trim="inbound.stream.xtls.server"></a-input> </a-form-item> diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html index 6fdf0c43..a66e84a9 100644 --- a/web/html/xui/inbounds.html +++ b/web/html/xui/inbounds.html @@ -105,6 +105,10 @@ </a-col> </a-row> </div> + <a-switch v-model="enableFilter" + checked-children='{{ i18n "search" }}' un-checked-children='{{ i18n "filter" }}' + @change="toggleFilter" style="margin-right: 10px;"> + </a-switch> <a-input v-if="!enableFilter" v-model.lazy="searchKey" placeholder='{{ i18n "search" }}' autofocus style="max-width: 300px"></a-input> <a-radio-group v-if="enableFilter" v-model="filterBy" @change="filterInbounds" button-style="solid"> <a-radio-button value="">{{ i18n "none" }}</a-radio-button> @@ -112,10 +116,6 @@ <a-radio-button value="depleted">{{ i18n "depleted" }}</a-radio-button> <a-radio-button value="expiring">{{ i18n "depletingSoon" }}</a-radio-button> </a-radio-group> - <a-switch v-model="enableFilter" - checked-children='{{ i18n "search" }}' un-checked-children='{{ i18n "filter" }}' - @change="toggleFilter"> - </a-switch> <a-table :columns="columns" :row-key="dbInbound => dbInbound.id" :data-source="searchedInbounds" :loading="spinning" :scroll="{ x: 1300 }" diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html index 3dd1f57b..f5ea4994 100644 --- a/web/html/xui/settings.html +++ b/web/html/xui/settings.html @@ -23,6 +23,34 @@ :not(.ant-card-dark)>.ant-tabs-top-bar { background: white; } + + .alert-msg { + color: rgb(194, 117, 18); + font-weight: bold; + font-size: 20px; + margin-top: 5px; + padding: 16px 6px; + text-align: center; + border-bottom: 1px solid; + } + + .alert-msg > i { + color: inherit; + font-size: 24px; + } + + .collapse-title { + color: inherit; + font-weight: bold; + font-size: 18px; + padding: 10px 20px; + border-bottom: 2px solid; + } + + .collapse-title > i { + color: inherit; + font-size: 24px; + } </style> <body> <a-layout id="app" v-cloak> @@ -35,8 +63,14 @@ <a-button type="primary" :disabled="saveBtnDisable" @click="updateAllSetting">{{ i18n "pages.settings.save" }}</a-button> <a-button type="danger" :disabled="!saveBtnDisable" @click="restartPanel">{{ i18n "pages.settings.restartPanel" }}</a-button> </a-space> - <a-tabs style="margin:1rem 0.5rem;" default-active-key="1" :class="themeSwitcher.darkCardClass" > + <a-tabs style="margin:1rem 0.5rem;" default-active-key="1" :class="themeSwitcher.darkCardClass"> <a-tab-pane key="1" tab='{{ i18n "pages.settings.panelSettings"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="alert-msg"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.infoDesc" }} + </h2> + </a-row> <a-list item-layout="horizontal" :style="themeSwitcher.textStyle"> <setting-list-item type="text" title='{{ i18n "pages.settings.panelListeningIP"}}' desc='{{ i18n "pages.settings.panelListeningIPDesc"}}' v-model="allSetting.webListen"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.panelPort"}}' desc='{{ i18n "pages.settings.panelPortDesc"}}' v-model="allSetting.webPort" :min="0"></setting-list-item> @@ -72,12 +106,6 @@ </a-row> </a-list-item> </a-list> - <a-row :xs="24" :sm="24" :lg="12"> - <h2 style="color: inherit; font-weight: bold; font-size: 16px; padding: 5px 5px; text-align: center;"> - <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon> - {{ i18n "pages.settings.infoDesc" }} - </h2> - </a-row> </a-tab-pane> <a-tab-pane key="2" tab='{{ i18n "pages.settings.securitySettings"}}' style="padding: 20px;"> <a-tabs class="ant-card-dark-securitybox-nohover" default-active-key="sec-1" :class="themeSwitcher.darkCardClass"> @@ -144,8 +172,8 @@ </a-space> <a-divider style="padding: 20px;">{{ i18n "pages.settings.templates.title"}} </a-divider> <a-row :xs="24" :sm="24" :lg="12"> - <h2 style="color: inherit; font-weight: bold; font-size: 16px; padding: 5px 5px; text-align: center;"> - <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon> + <h2 class="alert-msg"> + <a-icon type="warning"></a-icon> {{ i18n "pages.settings.infoDesc" }} </h2> </a-row> @@ -154,8 +182,8 @@ <a-collapse> <a-collapse-panel header='{{ i18n "pages.settings.templates.generalConfigs"}}'> <a-row :xs="24" :sm="24" :lg="12"> - <h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;"> - <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> {{ i18n "pages.settings.templates.generalConfigsDesc" }} </h2> </a-row> @@ -199,8 +227,8 @@ </a-collapse-panel> <a-collapse-panel header='{{ i18n "pages.settings.templates.blockConfigs"}}'> <a-row :xs="24" :sm="24" :lg="12"> - <h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;"> - <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> {{ i18n "pages.settings.templates.blockConfigsDesc" }} </h2> </a-row> @@ -212,8 +240,8 @@ </a-collapse-panel> <a-collapse-panel header='{{ i18n "pages.settings.templates.blockCountryConfigs"}}'> <a-row :xs="24" :sm="24" :lg="12"> - <h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;"> - <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> {{ i18n "pages.settings.templates.blockCountryConfigsDesc" }} </h2> </a-row> @@ -226,8 +254,8 @@ </a-collapse-panel> <a-collapse-panel header='{{ i18n "pages.settings.templates.directCountryConfigs"}}'> <a-row :xs="24" :sm="24" :lg="12"> - <h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;"> - <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon> + <h2 class="collapse-title"> +
|
