mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-05-13 15:06:46 +00:00
Merge 29fa28bf75 into 07bc74a521
This commit is contained in:
commit
8ad9b73d35
16 changed files with 7956 additions and 8449 deletions
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/mhsanaei/3x-ui/v3/util/crypto"
|
||||
"github.com/mhsanaei/3x-ui/v3/web/entity"
|
||||
"github.com/mhsanaei/3x-ui/v3/web/locale"
|
||||
"github.com/mhsanaei/3x-ui/v3/web/service"
|
||||
"github.com/mhsanaei/3x-ui/v3/web/session"
|
||||
|
||||
|
|
@ -77,6 +78,9 @@ func (a *SettingController) updateSetting(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
err = a.settingService.UpdateAllSetting(allSetting)
|
||||
if err == nil {
|
||||
locale.UpdateBotLocalizer(allSetting.TgLang)
|
||||
}
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,11 +111,20 @@ func initTGBotLocalizer(settingService SettingService) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Infof("Initializing TG Bot localizer with language: %s", botLang)
|
||||
|
||||
LocalizerBot = i18n.NewLocalizer(i18nBundle, botLang)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateBotLocalizer dynamically updates the bot localizer language.
|
||||
func UpdateBotLocalizer(botLang string) {
|
||||
if i18nBundle != nil {
|
||||
logger.Infof("Updating TG Bot localizer with language: %s", botLang)
|
||||
LocalizerBot = i18n.NewLocalizer(i18nBundle, botLang)
|
||||
}
|
||||
}
|
||||
|
||||
// LocalizerMiddleware returns a Gin middleware that sets up localization for web requests.
|
||||
// It determines the user's language from cookies or Accept-Language header,
|
||||
// creates a localizer instance, and stores it in the Gin context for use in handlers.
|
||||
|
|
@ -161,7 +170,9 @@ func loadTranslationsFromDisk(bundle *i18n.Bundle) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bundle.ParseMessageFileBytes(data, path)
|
||||
filename := d.Name()
|
||||
logger.Infof("Parsing translation file from disk: %s", filename)
|
||||
_, err = bundle.ParseMessageFileBytes(data, filename)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
|
@ -183,7 +194,9 @@ func parseTranslationFiles(i18nFS embed.FS, i18nBundle *i18n.Bundle) error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = i18nBundle.ParseMessageFileBytes(data, path)
|
||||
filename := d.Name()
|
||||
logger.Infof("Parsing translation file from embed: %s (path: %s)", filename, path)
|
||||
_, err = i18nBundle.ParseMessageFileBytes(data, filename)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
|||
3001
web/service/tgbot.go
3001
web/service/tgbot.go
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -873,6 +873,11 @@
|
|||
"exhaustedMsg": "🚨 Exhausted {{ .Type }}:\r\n",
|
||||
"exhaustedCount": "🚨 Exhausted {{ .Type }} count:\r\n",
|
||||
"onlinesCount": "🌐 Online Clients: {{ .Count }}\r\n",
|
||||
"cpu": "CPU: {{ .Usage }}%\r\n",
|
||||
"mem": "RAM: {{ .Usage }}/{{ .Total }}\r\n",
|
||||
"swap": "Swap: {{ .Usage }}/{{ .Total }}\r\n",
|
||||
"disk": "Disk: {{ .Usage }}/{{ .Total }}\r\n",
|
||||
"uptime": "Uptime: {{ .Time }}\r\n",
|
||||
"disabled": "🛑 Disabled: {{ .Disabled }}\r\n",
|
||||
"depleteSoon": "🔜 Deplete Soon: {{ .Deplete }}\r\n\r\n",
|
||||
"backupTime": "🗄 Backup Time: {{ .Time }}\r\n",
|
||||
|
|
@ -883,9 +888,13 @@
|
|||
"received_password": "🔑📥 Password updated.",
|
||||
"received_email": "📧📥 Email updated.",
|
||||
"received_comment": "💬📥 Comment updated.",
|
||||
"received_subid": "Sub ID updated successfully!",
|
||||
"client_subid": "Sub ID:",
|
||||
"client_flow": "Flow:",
|
||||
"id_prompt": "🔑 Default ID: {{ .ClientId }}\n\nEnter your id.",
|
||||
"pass_prompt": "🔑 Default Password: {{ .ClientPassword }}\n\nEnter your password.",
|
||||
"email_prompt": "📧 Default Email: {{ .ClientEmail }}\n\nEnter your email.",
|
||||
"subid_prompt": "Please enter new Sub ID:\nCurrent: {{.ClientSubId}}",
|
||||
"comment_prompt": "💬 Default Comment: {{ .ClientComment }}\n\nEnter your Comment.",
|
||||
"inbound_client_data_id": "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n🌐 IP Limit: {{ .IpLimit }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!",
|
||||
"inbound_client_data_pass": "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 Password: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n🌐 IP Limit: {{ .IpLimit }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!",
|
||||
|
|
@ -893,6 +902,7 @@
|
|||
"error_add_client": "⚠️ Error:\n\n {{ .error }}",
|
||||
"using_default_value": "Okay, I'll stick with the default value. 😊",
|
||||
"incorrect_input": "Your input is not valid.\nThe phrases should be continuous without spaces.\nCorrect example: aaaaaa\nIncorrect example: aaa aaa 🚫",
|
||||
"invalid_subid": "Invalid format.\nSub ID can only contain letters, numbers, hyphens (-), and underscores (_).\nSpaces and special characters are not allowed. 🚫",
|
||||
"AreYouSure": "Are you sure? 🤔",
|
||||
"SuccessResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Result: ✅ Success",
|
||||
"FailedResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Result: ❌ Failed \n\n🛠️ Error: [ {{ .ErrorMessage }} ]",
|
||||
|
|
@ -939,6 +949,11 @@
|
|||
"change_password": "⚙️🔑 Password",
|
||||
"change_email": "⚙️📧 Email",
|
||||
"change_comment": "⚙️💬 Comment",
|
||||
"change_subid": "📝 Sub ID",
|
||||
"change_flow": "🌊 Flow",
|
||||
"flow_none": "None",
|
||||
"qrCode": "QR Code",
|
||||
"selectTGUser": "Select Telegram User",
|
||||
"ResetAllTraffics": "Reset All Traffics",
|
||||
"SortedTrafficUsageReport": "Sorted Traffic Usage Report"
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -883,9 +883,11 @@
|
|||
"received_password": "🔑📥 رمز عبور بهروزرسانی شد.",
|
||||
"received_email": "📧📥 ایمیل بهروزرسانی شد.",
|
||||
"received_comment": "💬📥 نظر بهروزرسانی شد.",
|
||||
"received_subid": "Sub ID با موفقیت تغییر کرد!",
|
||||
"id_prompt": "🔑 شناسه پیشفرض: {{ .ClientId }}\n\nشناسه خود را وارد کنید.",
|
||||
"pass_prompt": "🔑 رمز عبور پیشفرض: {{ .ClientPassword }}\n\nرمز عبور خود را وارد کنید.",
|
||||
"email_prompt": "📧 ایمیل پیشفرض: {{ .ClientEmail }}\n\nایمیل خود را وارد کنید.",
|
||||
"subid_prompt": "لطفاً Sub ID جدید را وارد کنید:\nفعلی: {{.ClientSubId}}",
|
||||
"comment_prompt": "💬 نظر پیشفرض: {{ .ClientComment }}\n\nنظر خود را وارد کنید.",
|
||||
"inbound_client_data_id": "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 شناسه: {{ .ClientId }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n🌐 محدودیت IP: {{ .IpLimit }}\n💬 توضیح: {{ .ClientComment }}\n\nاکنون میتونی مشتری را به ورودی اضافه کنی!",
|
||||
"inbound_client_data_pass": "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 رمز عبور: {{ .ClientPass }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n🌐 محدودیت IP: {{ .IpLimit }}\n💬 توضیح: {{ .ClientComment }}\n\nاکنون میتونی مشتری را به ورودی اضافه کنی!",
|
||||
|
|
@ -893,6 +895,9 @@
|
|||
"error_add_client": "⚠️ خطا:\n\n {{ .error }}",
|
||||
"using_default_value": "باشه، از مقدار پیشفرض استفاده میکنم. 😊",
|
||||
"incorrect_input": "ورودی شما معتبر نیست.\nعبارتها باید بدون فاصله باشند.\nمثال صحیح: aaaaaa\nمثال نادرست: aaa aaa 🚫",
|
||||
"invalid_subid": "فرمت نامعتبر است.\nشناسه Sub ID فقط میتواند شامل حروف، اعداد، خط تیره (-) و خط زیر (_) باشد.\nاستفاده از فاصله و کاراکترهای خاص مجاز نیست. 🚫",
|
||||
"client_subid": "شناسه اشتراک (Sub ID):",
|
||||
"client_flow": "جریان (Flow):",
|
||||
"AreYouSure": "مطمئنی؟ 🤔",
|
||||
"SuccessResetTraffic": "📧 ایمیل: {{ .ClientEmail }}\n🏁 نتیجه: ✅ موفقیتآمیز",
|
||||
"FailedResetTraffic": "📧 ایمیل: {{ .ClientEmail }}\n🏁 نتیجه: ❌ ناموفق \n\n🛠️ خطا: [ {{ .ErrorMessage }} ]",
|
||||
|
|
@ -939,6 +944,9 @@
|
|||
"change_password": "⚙️🔑 گذرواژه",
|
||||
"change_email": "⚙️📧 ایمیل",
|
||||
"change_comment": "⚙️💬 نظر",
|
||||
"change_subid": "📝 Sub ID",
|
||||
"change_flow": "🌊 Flow",
|
||||
"flow_none": "هیچ",
|
||||
"ResetAllTraffics": "بازنشانی همه ترافیکها",
|
||||
"SortedTrafficUsageReport": "گزارش استفاده از ترافیک مرتبشده"
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -873,6 +873,11 @@
|
|||
"exhaustedMsg": "🚨 Исчерпаны {{ .Type }}:\r\n",
|
||||
"exhaustedCount": "🚨 Количество исчерпанных {{ .Type }}:\r\n",
|
||||
"onlinesCount": "🌐 Клиентов онлайн: {{ .Count }}\r\n",
|
||||
"cpu": "ЦП: {{ .Usage }}%\r\n",
|
||||
"mem": "ОЗУ: {{ .Usage }}/{{ .Total }}\r\n",
|
||||
"swap": "Swap: {{ .Usage }}/{{ .Total }}\r\n",
|
||||
"disk": "Диск: {{ .Usage }}/{{ .Total }}\r\n",
|
||||
"uptime": "Время работы: {{ .Time }}\r\n",
|
||||
"disabled": "🛑 Отключено: {{ .Disabled }}\r\n",
|
||||
"depleteSoon": "🔜 Клиенты, у которых скоро исчерпание: {{ .Deplete }}\r\n\r\n",
|
||||
"backupTime": "🗄 Время резервного копирования: {{ .Time }}\r\n",
|
||||
|
|
@ -883,9 +888,13 @@
|
|||
"received_password": "🔑📥 Пароль обновлён.",
|
||||
"received_email": "📧📥 Email обновлен.",
|
||||
"received_comment": "💬📥 Комментарий обновлён.",
|
||||
"received_subid": "Sub ID успешно обновлен!",
|
||||
"client_subid": "Sub ID:",
|
||||
"client_flow": "Flow:",
|
||||
"id_prompt": "🔑 Стандартный ID: {{ .ClientId }}\n\nВведите ваш ID.",
|
||||
"pass_prompt": "🔑 Стандартный пароль: {{ .ClientPassword }}\n\nВведите ваш пароль.",
|
||||
"email_prompt": "📧 Стандартный email: {{ .ClientEmail }}\n\nВведите ваш email.",
|
||||
"subid_prompt": "Пожалуйста, введите новый Sub ID:\nТекущий: {{.ClientSubId}}",
|
||||
"comment_prompt": "💬 Стандартный комментарий: {{ .ClientComment }}\n\nВведите ваш комментарий.",
|
||||
"inbound_client_data_id": "🔄 Входящие подключения: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Срок действия: {{ .ClientExp }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента в входящее подключение!",
|
||||
"inbound_client_data_pass": "🔄 Входящие подключения: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Срок действия: {{ .ClientExp }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента в входящее подключение!",
|
||||
|
|
@ -893,6 +902,7 @@
|
|||
"error_add_client": "⚠️ Ошибка:\n\n {{ .error }}",
|
||||
"using_default_value": "Используется значение по умолчанию👌",
|
||||
"incorrect_input": "Ваш ввод недействителен.\nФразы должны быть непрерывными без пробелов.\nПравильный пример: aaaaaa\nНеправильный пример: aaa aaa 🚫",
|
||||
"invalid_subid": "Некорректный формат.\nSub ID может содержать только буквы, цифры, дефис (-) и нижнее подчеркивание (_).\nПробелы и спецсимволы не допускаются. 🚫",
|
||||
"AreYouSure": "Вы уверены? 🤔",
|
||||
"SuccessResetTraffic": "📧 Почта: {{ .ClientEmail }}\n🏁 Результат: ✅ Успешно",
|
||||
"FailedResetTraffic": "📧 Почта: {{ .ClientEmail }}\n🏁 Результат: ❌ Неудача \n\n🛠️ Ошибка: [ {{ .ErrorMessage }} ]",
|
||||
|
|
@ -939,6 +949,10 @@
|
|||
"change_password": "⚙️🔑 Пароль",
|
||||
"change_email": "⚙️📧 Email",
|
||||
"change_comment": "⚙️💬 Комментарий",
|
||||
"change_subid": "📝 Sub ID",
|
||||
"change_flow": "🌊 Flow",
|
||||
"flow_none": "Отсутствует",
|
||||
"qrCode": "QR-код",
|
||||
"ResetAllTraffics": "Сбросить весь трафик",
|
||||
"SortedTrafficUsageReport": "Отсортированный отчет об использовании трафика"
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -883,9 +883,13 @@
|
|||
"received_password": "🔑📥 Mật khẩu đã được cập nhật.",
|
||||
"received_email": "📧📥 Email đã được cập nhật.",
|
||||
"received_comment": "💬📥 Bình luận đã được cập nhật.",
|
||||
"id_prompt": "🔑 ID mặc định: {{ .ClientId }}\n\nVui lòng nhập ID của bạn.",
|
||||
"received_subid": "Sub ID đã được thay đổi thành công!",
|
||||
"client_subid": "Sub ID:",
|
||||
"client_flow": "Flow:",
|
||||
"id_prompt": "🔑 ID mặc định: {{ .ClientId }}\n\nV Vui lòng nhập ID của bạn.",
|
||||
"pass_prompt": "🔑 Mật khẩu mặc định: {{ .ClientPassword }}\n\nVui lòng nhập mật khẩu của bạn.",
|
||||
"email_prompt": "📧 Email mặc định: {{ .ClientEmail }}\n\nVui lòng nhập email của bạn.",
|
||||
"subid_prompt": "Vui lòng nhập Sub ID mới:\nHiện tại: {{.ClientSubId}}",
|
||||
"comment_prompt": "💬 Bình luận mặc định: {{ .ClientComment }}\n\nVui lòng nhập bình luận của bạn.",
|
||||
"inbound_client_data_id": "🔄 Kết nối vào: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Dung lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n🌐 Giới hạn IP: {{ .IpLimit }}\n💬 Ghi chú: {{ .ClientComment }}\n\nBây giờ bạn có thể thêm khách hàng vào inbound!",
|
||||
"inbound_client_data_pass": "🔄 Kết nối vào: {{ .InboundRemark }}\n\n🔑 Mật khẩu: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Dung lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n🌐 Giới hạn IP: {{ .IpLimit }}\n💬 Ghi chú: {{ .ClientComment }}\n\nBây giờ bạn có thể thêm khách hàng vào inbound!",
|
||||
|
|
@ -893,6 +897,7 @@
|
|||
"error_add_client": "⚠️ Lỗi:\n\n {{ .error }}",
|
||||
"using_default_value": "Được rồi, tôi sẽ sử dụng giá trị mặc định. 😊",
|
||||
"incorrect_input": "Dữ liệu bạn nhập không hợp lệ.\nCác chuỗi phải liền mạch và không có dấu cách.\nVí dụ đúng: aaaaaa\nVí dụ sai: aaa aaa 🚫",
|
||||
"invalid_subid": "Định dạng không hợp lệ.\nSub ID chỉ có thể chứa chữ cái, số, dấu gạch ngang (-) và dấu gạch dưới (_).\nKhông cho phép khoảng trắng và các ký tự đặc biệt. 🚫",
|
||||
"AreYouSure": "Bạn có chắc không? 🤔",
|
||||
"SuccessResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Kết quả: ✅ Thành công",
|
||||
"FailedResetTraffic": "📧 Email: {{ .ClientEmail }}\n🏁 Kết quả: ❌ Thất bại \n\n🛠️ Lỗi: [ {{ .ErrorMessage }} ]",
|
||||
|
|
@ -939,6 +944,9 @@
|
|||
"change_password": "⚙️🔑 Mật Khẩu",
|
||||
"change_email": "⚙️📧 Email",
|
||||
"change_comment": "⚙️💬 Bình Luận",
|
||||
"change_subid": "📝 Sub ID",
|
||||
"change_flow": "🌊 Flow",
|
||||
"flow_none": "None",
|
||||
"ResetAllTraffics": "Đặt lại tất cả lưu lượng",
|
||||
"SortedTrafficUsageReport": "Báo cáo sử dụng lưu lượng đã sắp xếp"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -883,9 +883,13 @@
|
|||
"received_password": "🔑📥 密码已更新。",
|
||||
"received_email": "📧📥 邮箱已更新。",
|
||||
"received_comment": "💬📥 评论已更新。",
|
||||
"received_subid": "Sub ID 修改成功!",
|
||||
"client_subid": "Sub ID:",
|
||||
"client_flow": "Flow:",
|
||||
"id_prompt": "🔑 默认 ID: {{ .ClientId }}\n\n请输入您的 ID。",
|
||||
"pass_prompt": "🔑 默认密码: {{ .ClientPassword }}\n\n请输入您的密码。",
|
||||
"email_prompt": "📧 默认邮箱: {{ .ClientEmail }}\n\n请输入您的邮箱。",
|
||||
"subid_prompt": "请输入新的 Sub ID:\n当前: {{.ClientSubId}}",
|
||||
"comment_prompt": "💬 默认评论: {{ .ClientComment }}\n\n请输入您的评论。",
|
||||
"inbound_client_data_id": "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日期: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 备注: {{ .ClientComment }}\n\n你现在可以将客户添加到入站了!",
|
||||
"inbound_client_data_pass": "🔄 入站: {{ .InboundRemark }}\n\n🔑 密码: {{ .ClientPass }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日期: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 备注: {{ .ClientComment }}\n\n你现在可以将客户添加到入站了!",
|
||||
|
|
@ -893,6 +897,7 @@
|
|||
"error_add_client": "⚠️ 错误:\n\n {{ .error }}",
|
||||
"using_default_value": "好的,我会使用默认值。 😊",
|
||||
"incorrect_input": "您的输入无效。\n短语应连续输入,不能有空格。\n正确示例: aaaaaa\n错误示例: aaa aaa 🚫",
|
||||
"invalid_subid": "格式无效。\nSub ID 只能包含字母、数字、连字符 (-) 和下划线 (_)。\n不允许使用空格和特殊字符。 🚫",
|
||||
"AreYouSure": "你确定吗?🤔",
|
||||
"SuccessResetTraffic": "📧 邮箱: {{ .ClientEmail }}\n🏁 结果: ✅ 成功",
|
||||
"FailedResetTraffic": "📧 邮箱: {{ .ClientEmail }}\n🏁 结果: ❌ 失败 \n\n🛠️ 错误: [ {{ .ErrorMessage }} ]",
|
||||
|
|
@ -939,6 +944,9 @@
|
|||
"change_password": "⚙️🔑 密码",
|
||||
"change_email": "⚙️📧 邮箱",
|
||||
"change_comment": "⚙️💬 评论",
|
||||
"change_subid": "📝 Sub ID",
|
||||
"change_flow": "🌊 Flow",
|
||||
"flow_none": "无",
|
||||
"ResetAllTraffics": "重置所有流量",
|
||||
"SortedTrafficUsageReport": "排序的流量使用报告"
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue