mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 13:32:24 +00:00
separate xray page #1286
This commit is contained in:
parent
a8b7063647
commit
2a8da2ba3c
12 changed files with 211 additions and 84 deletions
|
@ -41,7 +41,7 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) {
|
|||
g.POST("/update", a.updateSetting)
|
||||
g.POST("/updateUser", a.updateUser)
|
||||
g.POST("/restartPanel", a.restartPanel)
|
||||
g.GET("/getDefaultJsonConfig", a.getDefaultJsonConfig)
|
||||
g.GET("/getDefaultJsonConfig", a.getDefaultXrayConfig)
|
||||
g.POST("/updateUserSecret", a.updateSecret)
|
||||
g.POST("/getUserSecret", a.getUserSecret)
|
||||
}
|
||||
|
@ -55,15 +55,6 @@ func (a *SettingController) getAllSetting(c *gin.Context) {
|
|||
jsonObj(c, allSetting, nil)
|
||||
}
|
||||
|
||||
func (a *SettingController) getDefaultJsonConfig(c *gin.Context) {
|
||||
defaultJsonConfig, err := a.settingService.GetDefaultJsonConfig()
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err)
|
||||
return
|
||||
}
|
||||
jsonObj(c, defaultJsonConfig, nil)
|
||||
}
|
||||
|
||||
func (a *SettingController) getDefaultSettings(c *gin.Context) {
|
||||
type settingFunc func() (interface{}, error)
|
||||
|
||||
|
@ -169,3 +160,12 @@ func (a *SettingController) getUserSecret(c *gin.Context) {
|
|||
jsonObj(c, user, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *SettingController) getDefaultXrayConfig(c *gin.Context) {
|
||||
defaultJsonConfig, err := a.settingService.GetDefaultXrayConfig()
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err)
|
||||
return
|
||||
}
|
||||
jsonObj(c, defaultJsonConfig, nil)
|
||||
}
|
||||
|
|
50
web/controller/xraySetting.go
Normal file
50
web/controller/xraySetting.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"x-ui/web/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type XraySettingController struct {
|
||||
XraySettingService service.XraySettingService
|
||||
SettingService service.SettingService
|
||||
}
|
||||
|
||||
func NewXraySettingController(g *gin.RouterGroup) *XraySettingController {
|
||||
a := &XraySettingController{}
|
||||
a.initRouter(g)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *XraySettingController) initRouter(g *gin.RouterGroup) {
|
||||
g = g.Group("/xray")
|
||||
|
||||
g.POST("/", a.getXraySetting)
|
||||
g.POST("/update", a.updateSetting)
|
||||
g.GET("/getDefaultJsonConfig", a.getDefaultXrayConfig)
|
||||
}
|
||||
|
||||
func (a *XraySettingController) getXraySetting(c *gin.Context) {
|
||||
xraySetting, err := a.SettingService.GetXrayConfigTemplate()
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err)
|
||||
return
|
||||
}
|
||||
jsonObj(c, xraySetting, nil)
|
||||
}
|
||||
|
||||
func (a *XraySettingController) updateSetting(c *gin.Context) {
|
||||
xraySetting := c.PostForm("xraySetting")
|
||||
err := a.XraySettingService.SaveXraySetting(xraySetting)
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
||||
}
|
||||
|
||||
func (a *XraySettingController) getDefaultXrayConfig(c *gin.Context) {
|
||||
defaultJsonConfig, err := a.SettingService.GetDefaultXrayConfig()
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.getSettings"), err)
|
||||
return
|
||||
}
|
||||
jsonObj(c, defaultJsonConfig, nil)
|
||||
}
|
|
@ -7,8 +7,9 @@ import (
|
|||
type XUIController struct {
|
||||
BaseController
|
||||
|
||||
inboundController *InboundController
|
||||
settingController *SettingController
|
||||
inboundController *InboundController
|
||||
settingController *SettingController
|
||||
xraySettingController *XraySettingController
|
||||
}
|
||||
|
||||
func NewXUIController(g *gin.RouterGroup) *XUIController {
|
||||
|
@ -24,9 +25,11 @@ func (a *XUIController) initRouter(g *gin.RouterGroup) {
|
|||
g.GET("/", a.index)
|
||||
g.GET("/inbounds", a.inbounds)
|
||||
g.GET("/settings", a.settings)
|
||||
g.GET("/xray", a.xraySettings)
|
||||
|
||||
a.inboundController = NewInboundController(g)
|
||||
a.settingController = NewSettingController(g)
|
||||
a.xraySettingController = NewXraySettingController(g)
|
||||
}
|
||||
|
||||
func (a *XUIController) index(c *gin.Context) {
|
||||
|
@ -40,3 +43,7 @@ func (a *XUIController) inbounds(c *gin.Context) {
|
|||
func (a *XUIController) settings(c *gin.Context) {
|
||||
html(c, "settings.html", "pages.settings.title", nil)
|
||||
}
|
||||
|
||||
func (a *XUIController) xraySettings(c *gin.Context) {
|
||||
html(c, "xray.html", "pages.xray.title", nil)
|
||||
}
|
||||
|
|
|
@ -2,12 +2,10 @@ package entity
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
"x-ui/util/common"
|
||||
"x-ui/xray"
|
||||
)
|
||||
|
||||
type Msg struct {
|
||||
|
@ -27,36 +25,35 @@ type Pager struct {
|
|||
}
|
||||
|
||||
type AllSetting struct {
|
||||
WebListen string `json:"webListen" form:"webListen"`
|
||||
WebDomain string `json:"webDomain" form:"webDomain"`
|
||||
WebPort int `json:"webPort" form:"webPort"`
|
||||
WebCertFile string `json:"webCertFile" form:"webCertFile"`
|
||||
WebKeyFile string `json:"webKeyFile" form:"webKeyFile"`
|
||||
WebBasePath string `json:"webBasePath" form:"webBasePath"`
|
||||
SessionMaxAge int `json:"sessionMaxAge" form:"sessionMaxAge"`
|
||||
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"`
|
||||
TgBotLoginNotify bool `json:"tgBotLoginNotify" form:"tgBotLoginNotify"`
|
||||
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"`
|
||||
SubEnable bool `json:"subEnable" form:"subEnable"`
|
||||
SubListen string `json:"subListen" form:"subListen"`
|
||||
SubPort int `json:"subPort" form:"subPort"`
|
||||
SubPath string `json:"subPath" form:"subPath"`
|
||||
SubDomain string `json:"subDomain" form:"subDomain"`
|
||||
SubCertFile string `json:"subCertFile" form:"subCertFile"`
|
||||
SubKeyFile string `json:"subKeyFile" form:"subKeyFile"`
|
||||
SubUpdates int `json:"subUpdates" form:"subUpdates"`
|
||||
SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"`
|
||||
SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"`
|
||||
WebListen string `json:"webListen" form:"webListen"`
|
||||
WebDomain string `json:"webDomain" form:"webDomain"`
|
||||
WebPort int `json:"webPort" form:"webPort"`
|
||||
WebCertFile string `json:"webCertFile" form:"webCertFile"`
|
||||
WebKeyFile string `json:"webKeyFile" form:"webKeyFile"`
|
||||
WebBasePath string `json:"webBasePath" form:"webBasePath"`
|
||||
SessionMaxAge int `json:"sessionMaxAge" form:"sessionMaxAge"`
|
||||
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"`
|
||||
TgBotLoginNotify bool `json:"tgBotLoginNotify" form:"tgBotLoginNotify"`
|
||||
TgCpu int `json:"tgCpu" form:"tgCpu"`
|
||||
TgLang string `json:"tgLang" form:"tgLang"`
|
||||
TimeLocation string `json:"timeLocation" form:"timeLocation"`
|
||||
SecretEnable bool `json:"secretEnable" form:"secretEnable"`
|
||||
SubEnable bool `json:"subEnable" form:"subEnable"`
|
||||
SubListen string `json:"subListen" form:"subListen"`
|
||||
SubPort int `json:"subPort" form:"subPort"`
|
||||
SubPath string `json:"subPath" form:"subPath"`
|
||||
SubDomain string `json:"subDomain" form:"subDomain"`
|
||||
SubCertFile string `json:"subCertFile" form:"subCertFile"`
|
||||
SubKeyFile string `json:"subKeyFile" form:"subKeyFile"`
|
||||
SubUpdates int `json:"subUpdates" form:"subUpdates"`
|
||||
SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"`
|
||||
SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"`
|
||||
}
|
||||
|
||||
func (s *AllSetting) CheckValid() error {
|
||||
|
@ -107,13 +104,7 @@ func (s *AllSetting) CheckValid() error {
|
|||
s.WebBasePath += "/"
|
||||
}
|
||||
|
||||
xrayConfig := &xray.Config{}
|
||||
err := json.Unmarshal([]byte(s.XrayTemplateConfig), xrayConfig)
|
||||
if err != nil {
|
||||
return common.NewError("xray template config invalid:", err)
|
||||
}
|
||||
|
||||
_, err = time.LoadLocation(s.TimeLocation)
|
||||
_, err := time.LoadLocation(s.TimeLocation)
|
||||
if err != nil {
|
||||
return common.NewError("time location not exist:", s.TimeLocation)
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ func (s *SettingService) GetDefaultJsonConfig() (interface{}, error) {
|
|||
func (s *SettingService) GetAllSetting() (*entity.AllSetting, error) {
|
||||
db := database.GetDB()
|
||||
settings := make([]*model.Setting, 0)
|
||||
err := db.Model(model.Setting{}).Find(&settings).Error
|
||||
err := db.Model(model.Setting{}).Not("key = ?", "xrayTemplateConfig").Find(&settings).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -426,3 +426,12 @@ func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error {
|
|||
}
|
||||
return common.Combine(errs...)
|
||||
}
|
||||
|
||||
func (s *SettingService) GetDefaultXrayConfig() (interface{}, error) {
|
||||
var jsonData interface{}
|
||||
err := json.Unmarshal([]byte(xrayTemplateConfig), &jsonData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return jsonData, nil
|
||||
}
|
||||
|
|
28
web/service/xraySettings.go
Normal file
28
web/service/xraySettings.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"x-ui/util/common"
|
||||
"x-ui/xray"
|
||||
)
|
||||
|
||||
type XraySettingService struct {
|
||||
SettingService
|
||||
}
|
||||
|
||||
func (s *XraySettingService) SaveXraySetting(newXraySettings string) error {
|
||||
if err := s.CheckXrayConfig(newXraySettings); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.SettingService.saveSetting("xrayTemplateConfig", newXraySettings)
|
||||
}
|
||||
|
||||
func (s *XraySettingService) CheckXrayConfig(XrayTemplateConfig string) error {
|
||||
xrayConfig := &xray.Config{}
|
||||
err := json.Unmarshal([]byte(XrayTemplateConfig), xrayConfig)
|
||||
if err != nil {
|
||||
return common.NewError("xray template config invalid:", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
"protocol" = "Protocol"
|
||||
"search" = "Search"
|
||||
"filter" = "Filter"
|
||||
"loading" = "Loading"
|
||||
"loading" = "Loading..."
|
||||
"second" = "Second"
|
||||
"minute" = "Minute"
|
||||
"hour" = "Hour"
|
||||
|
@ -37,7 +37,9 @@
|
|||
"enabled" = "Enabled"
|
||||
"disabled" = "Disabled"
|
||||
"depleted" = "Depleted"
|
||||
"depletingSoon" = "Depleting soon"
|
||||
"depletingSoon" = "Depleting"
|
||||
"offline" = "Offline"
|
||||
"online" = "Online"
|
||||
"domainName" = "Domain name"
|
||||
"monitor" = "Listening IP"
|
||||
"certificate" = "Certificate"
|
||||
|
@ -54,6 +56,7 @@
|
|||
"dashboard" = "System Status"
|
||||
"inbounds" = "Inbounds"
|
||||
"settings" = "Panel Settings"
|
||||
"xray" = "Xray Settings"
|
||||
"logout" = "Logout"
|
||||
"link" = "Other"
|
||||
|
||||
|
@ -121,6 +124,8 @@
|
|||
"modifyInbound" = "Modify Inbound"
|
||||
"deleteInbound" = "Delete Inbound"
|
||||
"deleteInboundContent" = "Confirm deletion of inbound?"
|
||||
"deleteClient" = "Delete Client"
|
||||
"deleteClientContent" = "Are you sure you want to delete client?"
|
||||
"resetTrafficContent" = "Confirm traffic reset?"
|
||||
"copyLink" = "Copy Link"
|
||||
"address" = "Address"
|
||||
|
@ -132,8 +137,8 @@
|
|||
"totalFlow" = "Total Flow"
|
||||
"leaveBlankToNeverExpire" = "Leave Blank to Never Expire"
|
||||
"noRecommendKeepDefault" = "No special requirements to maintain default settings"
|
||||
"certificatePath" = "Certificate File Path"
|
||||
"certificateContent" = "Certificate File Content"
|
||||
"certificatePath" = "File Path"
|
||||
"certificateContent" = "File Content"
|
||||
"publicKeyPath" = "Public Key Path"
|
||||
"publicKeyContent" = "Public Key Content"
|
||||
"keyPath" = "Private Key Path"
|
||||
|
@ -169,6 +174,7 @@
|
|||
"realityDesc" = "Xray core needs to be 1.8.0 or higher."
|
||||
"telegramDesc" = "use Telegram ID without @ or chat IDs ( you can get it here @userinfobot or use '/id' command in bot )"
|
||||
"subscriptionDesc" = "you can find your sub link on Details, also you can use the same name for several configurations"
|
||||
"info" = "Info"
|
||||
|
||||
[pages.client]
|
||||
"add" = "Add Client"
|
||||
|
@ -185,6 +191,8 @@
|
|||
"delayedStart" = "Start after first use"
|
||||
"expireDays" = "Expire days"
|
||||
"days" = "day(s)"
|
||||
"renew" = "Auto renew"
|
||||
"renewDesc" = "Auto renew days after expiration. 0 = disable"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "Obtain"
|
||||
|
@ -216,7 +224,6 @@
|
|||
"resetDefaultConfig" = "Reset to Default Configuration"
|
||||
"panelSettings" = "Panel Settings"
|
||||
"securitySettings" = "Security Settings"
|
||||
"xrayConfiguration" = "Xray Configuration"
|
||||
"TGBotSettings" = "Telegram Bot Settings"
|
||||
"panelListeningIP" = "Panel Listening IP"
|
||||
"panelListeningIPDesc" = "Leave blank by default to monitor all IPs."
|
||||
|
@ -278,8 +285,8 @@
|
|||
"subShowInfo" = "Show usage info"
|
||||
"subShowInfoDesc" = "Show remianed traffic and date after config name"
|
||||
|
||||
[pages.settings.templates]
|
||||
"title" = "Templates"
|
||||
[pages.xray]
|
||||
"title" = "Xray Settings"
|
||||
"basicTemplate" = "Basic Template"
|
||||
"advancedTemplate" = "Advanced Template"
|
||||
"completeTemplate" = "Complete Template"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"protocol" = "Protocolo"
|
||||
"search" = "Buscar"
|
||||
"filter" = "Filtrar"
|
||||
"loading" = "Cargando"
|
||||
"loading" = "Cargando..."
|
||||
"second" = "Segundo"
|
||||
"minute" = "Minuto"
|
||||
"hour" = "Hora"
|
||||
|
@ -37,7 +37,9 @@
|
|||
"enabled" = "Habilitado"
|
||||
"disabled" = "Deshabilitado"
|
||||
"depleted" = "Agotado"
|
||||
"depletingSoon" = "Agotándose pronto"
|
||||
"depletingSoon" = "Agotándose"
|
||||
"offline" = "fuera de línea"
|
||||
"online" = "en línea"
|
||||
"domainName" = "Nombre de dominio"
|
||||
"monitor" = "Listening IP"
|
||||
"certificate" = "Certificado"
|
||||
|
@ -54,6 +56,7 @@
|
|||
"dashboard" = "Estado del Sistema"
|
||||
"inbounds" = "Entradas"
|
||||
"settings" = "Configuraciones"
|
||||
"xray" = "Configuración Xray"
|
||||
"logout" = "Cerrar Sesión"
|
||||
"link" = "Otro"
|
||||
|
||||
|
@ -121,6 +124,8 @@
|
|||
"modifyInbound" = "Modificar Entrada"
|
||||
"deleteInbound" = "Eliminar Entrada"
|
||||
"deleteInboundContent" = "¿Confirmar eliminación de entrada?"
|
||||
"deleteClient" = "Eliminar cliente"
|
||||
"deleteClientContent" = "¿Está seguro de que desea eliminar el cliente?"
|
||||
"resetTrafficContent" = "¿Confirmar restablecimiento de tráfico?"
|
||||
"copyLink" = "Copiar Enlace"
|
||||
"address" = "Dirección"
|
||||
|
@ -132,8 +137,8 @@
|
|||
"totalFlow" = "Flujo Total"
|
||||
"leaveBlankToNeverExpire" = "Dejar en Blanco para Nunca Expirar"
|
||||
"noRecommendKeepDefault" = "No hay requisitos especiales para mantener la configuración predeterminada"
|
||||
"certificatePath" = "Ruta del Archivo de Certificado"
|
||||
"certificateContent" = "Contenido del Archivo de Certificado"
|
||||
"certificatePath" = "Ruta del Archivo"
|
||||
"certificateContent" = "Contenido del Archivo"
|
||||
"publicKeyPath" = "Ruta de la Clave Pública"
|
||||
"publicKeyContent" = "Contenido de la Clave Pública"
|
||||
"keyPath" = "Ruta de la Clave Privada"
|
||||
|
@ -169,6 +174,7 @@
|
|||
"realityDesc" = "La versión del núcleo de Xray debe ser 1.8.0 o superior."
|
||||
"telegramDesc" = "Utiliza el ID de Telegram sin @ o los IDs de chat (puedes obtenerlo aquí @userinfobot o usando el comando '/id' en el bot)."
|
||||
"subscriptionDesc" = "Puedes encontrar tu enlace de suscripción en Detalles, también puedes usar el mismo nombre para varias configuraciones."
|
||||
"info" = "Info"
|
||||
|
||||
[pages.client]
|
||||
"add" = "Agregar Cliente"
|
||||
|
@ -185,6 +191,8 @@
|
|||
"delayedStart" = "Iniciar después del primer uso"
|
||||
"expireDays" = "Días de Expiración"
|
||||
"days" = "día(s)"
|
||||
"renew" = "Renovación automática"
|
||||
"renewDesc" = "Renovación automática días después del vencimiento. 0 = deshabilitar"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "Recibir"
|
||||
|
@ -216,7 +224,6 @@
|
|||
"resetDefaultConfig" = "Restablecer a Configuración Predeterminada"
|
||||
"panelSettings" = "Configuraciones del Panel"
|
||||
"securitySettings" = "Configuraciones de Seguridad"
|
||||
"xrayConfiguration" = "Configuración de Xray"
|
||||
"TGBotSettings" = "Configuraciones de Bot de Telegram"
|
||||
"panelListeningIP" = "IP de Escucha del Panel"
|
||||
"panelListeningIPDesc" = "Dejar en blanco por defecto para monitorear todas las IPs."
|
||||
|
@ -278,8 +285,8 @@
|
|||
"subShowInfo" = "Mostrar información de uso"
|
||||
"subShowInfoDesc" = "Mostrar tráfico restante y fecha después del nombre de configuración."
|
||||
|
||||
[pages.settings.templates]
|
||||
"title" = "Plantillas"
|
||||
[pages.xray]
|
||||
"title" = "Xray Configuración"
|
||||
"basicTemplate" = "Plantilla Básica"
|
||||
"advancedTemplate" = "Plantilla Avanzada"
|
||||
"completeTemplate" = "Plantilla Completa"
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
"disabled" = "غیرفعال"
|
||||
"depleted" = "منقضی"
|
||||
"depletingSoon" = "در حال انقضا"
|
||||
"offline" = "آفلاین"
|
||||
"online" = "آنلاین"
|
||||
"domainName" = "آدرس دامنه"
|
||||
"monitor" = "آی پی اتصال"
|
||||
"certificate" = "گواهی دیجیتال"
|
||||
|
@ -54,6 +56,7 @@
|
|||
"dashboard" = "وضعیت سیستم"
|
||||
"inbounds" = "سرویس ها"
|
||||
"settings" = "تنظیمات پنل"
|
||||
"xray" = "الگوی ایکسری"
|
||||
"logout" = "خروج"
|
||||
"link" = "دیگر"
|
||||
|
||||
|
@ -121,6 +124,8 @@
|
|||
"modifyInbound" = "ویرایش سرویس"
|
||||
"deleteInbound" = "حذف سرویس"
|
||||
"deleteInboundContent" = "آیا مطمئن به حذف سرویس هستید ؟"
|
||||
"deleteClient" = "حذف کاربر"
|
||||
"deleteClientContent" = "آیا مطمئن به حذف کاربر هستید ؟"
|
||||
"resetTrafficContent" = "آیا مطمئن به ریست ترافیک هستید ؟"
|
||||
"copyLink" = "کپی لینک"
|
||||
"address" = "آدرس"
|
||||
|
@ -169,6 +174,7 @@
|
|||
"realityDesc" = "هسته Xray باید 1.8.0 و بالاتر باشد"
|
||||
"telegramDesc" = "از آیدی تلگرام بدون @ یا آیدی چت استفاده کنید (می توانید آن را از اینجا دریافت کنید @userinfobot یا در ربات دستور '/id' را وارد کنید)"
|
||||
"subscriptionDesc" = "می توانید ساب لینک خود را در جزئیات پیدا کنید، همچنین می توانید از همین نام برای چندین کانفیگ استفاده کنید"
|
||||
"info" = "اطلاعات"
|
||||
|
||||
[pages.client]
|
||||
"add" = "کاربر جدید"
|
||||
|
@ -185,6 +191,8 @@
|
|||
"delayedStart" = "شروع بعد از اولین استفاده"
|
||||
"expireDays" = "روزهای اعتبار"
|
||||
"days" = "(روز)"
|
||||
"renew" = "تمدید خودکار"
|
||||
"renewDesc" = "روزهای تمدید خودکار پس از انقضا. 0 = غیرفعال"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "Obtain"
|
||||
|
@ -216,7 +224,6 @@
|
|||
"resetDefaultConfig" = "برگشت به تنظیمات پیشفرض"
|
||||
"panelSettings" = "تنظیمات پنل"
|
||||
"securitySettings" = "تنظیمات امنیتی"
|
||||
"xrayConfiguration" = "تنظیمات Xray"
|
||||
"TGBotSettings" = "تنظیمات ربات تلگرام"
|
||||
"panelListeningIP" = "محدودیت آی پی پنل"
|
||||
"panelListeningIPDesc" = "برای استفاده از تمام آیپیها به طور پیش فرض خالی بگذارید"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"protocol" = "Протокол"
|
||||
"search" = "Поиск"
|
||||
"filter" = "Фильтр"
|
||||
"loading" = "Загрузка"
|
||||
"loading" = "Загрузка..."
|
||||
"second" = "Секунда"
|
||||
"minute" = "Минута"
|
||||
"hour" = "Час"
|
||||
|
@ -38,6 +38,8 @@
|
|||
"disabled" = "Отключено"
|
||||
"depleted" = "Исчерпано"
|
||||
"depletingSoon" = "Почти исчерпано"
|
||||
"offline" = "Офлайн"
|
||||
"online" = "Онлайн"
|
||||
"domainName" = "Домен"
|
||||
"monitor" = "Порт IP"
|
||||
"certificate" = "Сертификат"
|
||||
|
@ -54,6 +56,7 @@
|
|||
"dashboard" = "Статус системы"
|
||||
"inbounds" = "Подключения"
|
||||
"settings" = "Настройки панели"
|
||||
"xray" = "Xray Настройки"
|
||||
"logout" = "Выход"
|
||||
"link" = "Прочее"
|
||||
|
||||
|
@ -132,8 +135,8 @@
|
|||
"totalFlow" = "Общий расход"
|
||||
"leaveBlankToNeverExpire" = "Оставьте пустым, чтобы не истекало"
|
||||
"noRecommendKeepDefault" = "Нет требований для сохранения настроек по умолчанию"
|
||||
"certificatePath" = "Путь файла сертификата"
|
||||
"certificateContent" = "Содержимое файла сертификата"
|
||||
"certificatePath" = "Путь файла"
|
||||
"certificateContent" = "Содержимое файла"
|
||||
"publicKeyPath" = "Путь к публичному ключу"
|
||||
"publicKeyContent" = "Содержимое публичного ключа"
|
||||
"keyPath" = "Путь к приватному ключу"
|
||||
|
@ -169,6 +172,7 @@
|
|||
"realityDesc" = "Версия Xray должна быть не ниже 1.8.0"
|
||||
"telegramDesc" = "Используйте идентификатор Telegram без символа @ или идентификатора чата (можно получить его здесь @userinfobot или использовать команду '/id' в боте)"
|
||||
"subscriptionDesc" = "Вы можете найти свою ссылку подписки в разделе 'Подробнее', также вы можете использовать одно и то же имя для нескольких конфигураций"
|
||||
"info" = "Информация"
|
||||
|
||||
[pages.client]
|
||||
"add" = "Добавить пользователя"
|
||||
|
@ -185,6 +189,8 @@
|
|||
"delayedStart" = "Начать с момента первого подключения"
|
||||
"expireDays" = "Срок действия"
|
||||
"days" = "дней"
|
||||
"renew" = "Автопродление"
|
||||
"renewDesc" = "Автоматическое продление через несколько дней после истечения срока действия. 0 = отключить"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "Получить"
|
||||
|
@ -278,8 +284,8 @@
|
|||
"subShowInfo" = "Показать информацию об использовании"
|
||||
"subShowInfoDesc" = "Показывать восстановленный трафик и дату после имени конфигурации"
|
||||
|
||||
[pages.settings.templates]
|
||||
"title" = "Шаблоны"
|
||||
[pages.xray]
|
||||
"title" = "Xray Настройки"
|
||||
"basicTemplate" = "Базовый шаблон"
|
||||
"advancedTemplate" = "Расширенный шаблон"
|
||||
"completeTemplate" = "Полный шаблон"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"username" = "Tên người dùng"
|
||||
"password" = "Mật khẩu"
|
||||
"login" = "Đăng nhập"
|
||||
"login" = "Đăng nhập..."
|
||||
"confirm" = "Xác nhận"
|
||||
"cancel" = "Hủy bỏ"
|
||||
"close" = "Đóng"
|
||||
|
@ -37,7 +37,9 @@
|
|||
"enabled" = "Đã kích hoạt"
|
||||
"disabled" = "Đã tắt"
|
||||
"depleted" = "Đã cạn kiệt"
|
||||
"depletingSoon" = "Sắp cạn kiệt"
|
||||
"depletingSoon" = "Đang cạn kiệt"
|
||||
"offline" = "Ngoại tuyến"
|
||||
"online" = "Ngoại tuyến"
|
||||
"domainName" = "Tên miền"
|
||||
"monitor" = "Listening IP"
|
||||
"certificate" = "Chứng chỉ"
|
||||
|
@ -55,6 +57,7 @@
|
|||
"inbounds" = "Inbounds"
|
||||
"settings" = "Cài đặt bảng điều khiển"
|
||||
"logout" = "Đăng xuất"
|
||||
"xray" = "Xray Cài đặt"
|
||||
"link" = "Khác"
|
||||
|
||||
[pages.login]
|
||||
|
@ -121,6 +124,8 @@
|
|||
"modifyInbound" = "Chỉnh sửa điểm vào (Inbound)"
|
||||
"deleteInbound" = "Xóa điểm vào (Inbound)"
|
||||
"deleteInboundContent" = "Xác nhận xóa điểm vào? (Inbound)"
|
||||
"deleteClient" = "Xóa khách hàng"
|
||||
"deleteClientContent" = "Bạn có chắc chắn muốn xóa ứng dụng khách không?"
|
||||
"resetTrafficContent" = "Xác nhận đặt lại lưu lượng?"
|
||||
"copyLink" = "Sao chép liên kết"
|
||||
"address" = "Địa chỉ"
|
||||
|
@ -132,8 +137,8 @@
|
|||
"totalFlow" = "Tổng lưu lượng"
|
||||
"leaveBlankToNeverExpire" = "Để trống để không bao giờ hết hạn"
|
||||
"noRecommendKeepDefault" = "Không yêu cầu đặc biệt để giữ nguyên cài đặt mặc định"
|
||||
"certificatePath" = "Đường dẫn tập tin chứng chỉ"
|
||||
"certificateContent" = "Nội dung tập tin chứng chỉ"
|
||||
"certificatePath" = "Đường dẫn tập"
|
||||
"certificateContent" = "Nội dung tập"
|
||||
"publicKeyPath" = "Đường dẫn khóa công khai"
|
||||
"publicKeyContent" = "Nội dung khóa công khai"
|
||||
"keyPath" = "Đường dẫn khóa riêng tư"
|
||||
|
@ -169,6 +174,7 @@
|
|||
"realityDesc" = "Xray core cần phiên bản 1.8.0 hoặc cao hơn."
|
||||
"telegramDesc" = "Sử dụng Telegram ID mà không cần ký hiệu @ hoặc chat IDs (bạn có thể nhận được nó ở đây @userinfobot hoặc sử dụng lệnh '/id' trong bot)"
|
||||
"subscriptionDesc" = "Bạn có thể tìm liên kết đăng ký của mình trong Chi tiết, cũng như bạn có thể sử dụng cùng tên cho nhiều cấu hình khác nhau"
|
||||
"info" = "Thông tin"
|
||||
|
||||
[pages.client]
|
||||
"add" = "Thêm Client"
|
||||
|
@ -185,6 +191,8 @@
|
|||
"delayedStart" = "Bắt đầu sau khi sử dụng lần đầu"
|
||||
"expireDays" = "Số ngày hết hạn"
|
||||
"days" = "ngày"
|
||||
"renew" = "Tự động gia hạn"
|
||||
"renewDesc" = "Tự động gia hạn những ngày sau khi hết hạn. 0 = tắt"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "Nhận"
|
||||
|
@ -278,8 +286,8 @@
|
|||
"subShowInfo" = "Hiển thị thông tin sử dụng"
|
||||
"subShowInfoDesc" = "Hiển thị lưu lượng truy cập còn lại và ngày sau tên cấu hình"
|
||||
|
||||
[pages.settings.templates]
|
||||
"title" = "Mẫu"
|
||||
[pages.xray]
|
||||
"title" = "Xray Cài đặt"
|
||||
"basicTemplate" = "Mẫu Cơ bản"
|
||||
"advancedTemplate" = "Mẫu Nâng cao"
|
||||
"completeTemplate" = "Mẫu Đầy đủ"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"protocol" = "协议"
|
||||
"search" = "搜尋"
|
||||
"filter" = "过滤器"
|
||||
"loading" = "加载中"
|
||||
"loading" = "加载中..."
|
||||
"second" = "秒"
|
||||
"minute" = "分钟"
|
||||
"hour" = "小时"
|
||||
|
@ -38,6 +38,8 @@
|
|||
"disabled" = "关闭"
|
||||
"depleted" = "耗尽"
|
||||
"depletingSoon" = "即将耗尽"
|
||||
"offline" = "离线"
|
||||
"online" = "在线"
|
||||
"domainName" = "域名"
|
||||
"monitor" = "监听"
|
||||
"certificate" = "证书"
|
||||
|
@ -54,6 +56,7 @@
|
|||
"dashboard" = "系统状态"
|
||||
"inbounds" = "入站列表"
|
||||
"settings" = "面板设置"
|
||||
"xray" = "Xray 设置"
|
||||
"logout" = "退出登录"
|
||||
"link" = "其他"
|
||||
|
||||
|
@ -121,6 +124,8 @@
|
|||
"modifyInbound" = "修改入站"
|
||||
"deleteInbound" = "删除入站"
|
||||
"deleteInboundContent" = "确定要删除入站吗?"
|
||||
"deleteClient" = "删除客户端"
|
||||
"deleteClientContent" = "您确定要删除客户端吗?"
|
||||
"resetTrafficContent" = "确定要重置流量吗?"
|
||||
"copyLink" = "复制链接"
|
||||
"address" = "地址"
|
||||
|
@ -132,8 +137,8 @@
|
|||
"totalFlow" = "总流量"
|
||||
"leaveBlankToNeverExpire" = "留空则永不到期"
|
||||
"noRecommendKeepDefault" = "没有特殊需求保持默认即可"
|
||||
"certificatePath" = "证书文件路径"
|
||||
"certificateContent" = "证书文件内容"
|
||||
"certificatePath" = "文件路径"
|
||||
"certificateContent" = "文件内容"
|
||||
"publicKeyPath" = "公钥文件路径"
|
||||
"publicKeyContent" = "公钥内容"
|
||||
"keyPath" = "密钥文件路径"
|
||||
|
@ -169,6 +174,7 @@
|
|||
"realityDesc" = "Xray核心需要1.8.0及以上版本"
|
||||
"telegramDesc" = "使用 Telegram ID,不包含 @ 符号或聊天 ID(可以在 @userinfobot 处获取,或在机器人中使用'/id'命令)"
|
||||
"subscriptionDesc" = "您可以在详细信息上找到您的子链接,也可以对多个配置使用相同的名称"
|
||||
"info" = "信息"
|
||||
|
||||
[pages.client]
|
||||
"add" = "添加客户端"
|
||||
|
@ -185,6 +191,8 @@
|
|||
"delayedStart" = "首次使用后开始"
|
||||
"expireDays" = "过期天数"
|
||||
"days" = "天"
|
||||
"renew" = "自动续订"
|
||||
"renewDesc" = "过期后自动续订。0 = 禁用"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "获取"
|
||||
|
@ -216,7 +224,6 @@
|
|||
"resetDefaultConfig" = "重置为默认配置"
|
||||
"panelSettings" = "面板配置"
|
||||
"securitySettings" = "安全设定"
|
||||
"xrayConfiguration" = "xray 相关设置"
|
||||
"TGBotSettings" = "TG提醒相关设置"
|
||||
"panelListeningIP" = "面板监听 IP"
|
||||
"panelListeningIPDesc" = "默认留空监听所有 IP"
|
||||
|
@ -278,8 +285,8 @@
|
|||
"subShowInfo" = "显示使用信息"
|
||||
"subShowInfoDesc" = "在配置名称后显示剩余流量和日期"
|
||||
|
||||
[pages.settings.templates]
|
||||
"title" = "模板"
|
||||
[pages.xray]
|
||||
"title" = "Xray 设置"
|
||||
"basicTemplate" = "基本模板"
|
||||
"advancedTemplate" = "高级模板部件"
|
||||
"completeTemplate" = "Xray 配置的完整模板"
|
||||
|
|
Loading…
Reference in a new issue