i18n: add Vietnamese language support (#2568)

* i18n: add Vietnamese translation

* i18n: fix lint

* i18n: import fix

---------

Co-authored-by: meow <meow@air.local>
This commit is contained in:
wuys 2026-04-07 16:22:13 +07:00 committed by GitHub
parent 1eb9527175
commit b5c30f5dbe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 304 additions and 0 deletions

View file

@ -19,6 +19,7 @@ import nb from './locales/nb.json';
import bg from './locales/bg.json';
import gl from './locales/gl.json';
import cs from './locales/cs.json';
import vi from './locales/vi.json';
export default defineI18nConfig(() => ({
legacy: false,
@ -45,5 +46,6 @@ export default defineI18nConfig(() => ({
bg,
gl,
cs,
vi,
},
}));

297
src/i18n/locales/vi.json Normal file
View file

@ -0,0 +1,297 @@
{
"pages": {
"me": "Tài khoản",
"clients": "Người dùng",
"admin": {
"panel": "Bảng quản trị",
"general": "Chung",
"config": "Cấu hình",
"interface": "Giao diện mạng",
"hooks": "Hooks"
}
},
"user": {
"email": "E-Mail"
},
"me": {
"currentPassword": "Mật khẩu hiện tại",
"enable2fa": "Bật xác thực hai yếu tố",
"enable2faDesc": "Quét mã QR bằng ứng dụng xác thực của bạn hoặc nhập khóa thủ công.",
"2faKey": "Khóa TOTP",
"2faCodeDesc": "Nhập mã từ ứng dụng xác thực của bạn.",
"disable2fa": "Tắt xác thực hai yếu tố",
"disable2faDesc": "Nhập mật khẩu để tắt xác thực hai yếu tố."
},
"general": {
"name": "Tên",
"username": "Tên đăng nhập",
"password": "Mật khẩu",
"newPassword": "Mật khẩu mới",
"updatePassword": "Cập nhật mật khẩu",
"mtu": "MTU",
"allowedIps": "IP được phép",
"dns": "DNS",
"persistentKeepalive": "Persistent Keepalive",
"logout": "Đăng xuất",
"continue": "Tiếp tục",
"host": "Host",
"port": "Cổng",
"yes": "Có",
"no": "Chưa",
"confirmPassword": "Xác nhận mật khẩu",
"loading": "Đang tải...",
"2fa": "Xác thực hai yếu tố",
"2faCode": "Mã TOTP"
},
"setup": {
"welcome": "Chào mừng đến với thiết lập đầu tiên của wg-easy",
"welcomeDesc": "Bạn đã tìm thấy cách dễ nhất để cài đặt và quản lý WireGuard trên bất kỳ máy chủ Linux nào",
"existingSetup": "Bạn có hệ thống được cài đặt trước đây chưa?",
"createAdminDesc": "Vui lòng nhập tên đăng nhập quản trị viên và mật khẩu mạnh. Thông tin này sẽ được sử dụng để đăng nhập vào bảng quản trị của bạn.",
"setupConfigDesc": "Vui lòng cung cấp host và cổng. Những thông tin này sẽ được sử dụng để cấu hình WireGuard cho người dùng trên thiết bị của họ.",
"setupMigrationDesc": "Vui lòng cung cấp tệp sao lưu nếu bạn muốn chuyển dữ liệu từ phiên bản wg-easy trước sang cài đặt mới.",
"upload": "Tải lên",
"migration": "Khôi phục bản sao lưu:",
"createAccount": "Tạo tài khoản",
"successful": "Thiết lập thành công",
"hostDesc": "Tên miền công khai mà thiết bị sẽ kết nối tới",
"portDesc": "Cổng UDP công khai mà thiết bị sẽ kết nối và WireGuard sẽ sử dụng"
},
"update": {
"updateAvailable": "Có bản cập nhật mới!",
"update": "Cập nhật"
},
"theme": {
"dark": "Giao diện tối",
"light": "Giao diện sáng",
"system": "Giao diện hệ thống"
},
"layout": {
"toggleCharts": "Hiện/ẩn biểu đồ",
"donate": "Ủng hộ"
},
"login": {
"signIn": "Đăng nhập",
"rememberMe": "Duy trì đăng nhập",
"rememberMeDesc": "Duy trì trạng thái đăng nhập sau khi đóng trình duyệt",
"insecure": "Bạn không thể đăng nhập qua kết nối không bảo mật. Hãy dùng HTTPS.",
"2faRequired": "Yêu cầu xác thực hai yếu tố",
"2faWrong": "Mã xác thực hai yếu tố không đúng"
},
"client": {
"empty": "Chưa có người dùng nào.",
"newShort": "Mới",
"sort": "Sắp xếp",
"create": "Tạo người dùng",
"created": "Đã tạo người dùng",
"new": "Người dùng mới",
"name": "Tên",
"expireDate": "Ngày hết hạn",
"expireDateDesc": "Ngày người dùng sẽ bị vô hiệu hóa. Để trống nếu dùng vĩnh viễn",
"delete": "Xóa",
"deleteClient": "Xóa người dùng",
"deleteDialog1": "Bạn có chắc rằng muốn xóa",
"deleteDialog2": "Hành động này không thể hoàn tác.",
"enabled": "Đã bật",
"address": "Địa chỉ",
"serverAllowedIps": "IP được phép phía máy chủ",
"otlDesc": "Tạo liên kết dùng một lần",
"permanent": "Vĩnh viễn",
"createdOn": "Được tạo vào ",
"lastSeen": "Lần cuối trực tuyến ",
"totalDownload": "Tổng tải về: ",
"totalUpload": "Tổng tải lên: ",
"newClient": "Người dùng mới",
"disableClient": "Vô hiệu hóa người dùng",
"enableClient": "Kích hoạt người dùng",
"noPrivKey": "Người dùng này không có khóa riêng tư. Không thể tạo cấu hình.",
"showQR": "Hiển thị mã QR",
"downloadConfig": "Tải cấu hình",
"allowedIpsDesc": "Các IP sẽ được định tuyến qua VPN (ghi đè cấu hình chung)",
"serverAllowedIpsDesc": "Các IP mà máy chủ sẽ định tuyến đến người dùng",
"mtuDesc": "Đặt đơn vị truyền tải tối đa - MTU (kích thước gói tin) cho VPN",
"persistentKeepaliveDesc": "Đặt khoảng thời gian (giây) gửi gói tin keep-alive. 0 để tắt",
"hooks": "Hooks",
"hooksDescription": "Hooks chỉ hoạt động với wg-quick",
"hooksLeaveEmpty": "Chỉ dùng cho wg-quick. Nếu không, để trống",
"dnsDesc": "Máy chủ DNS mà người dùng sử dụng (ghi đè cấu hình chung)",
"notConnected": "Người dùng chưa kết nối",
"endpoint": "Điểm cuối",
"endpointDesc": "IP của người dùng dùng để thiết lập kết nối WireGuard",
"search": "Tìm kiếm người dùng...",
"config": "Cấu hình",
"viewConfig": "Xem cấu hình",
"firewallIps": "IP được phép qua tường lửa",
"firewallIpsDesc": "Địa chỉ IP/CIDR đích mà người dùng này có thể truy cập (kiểm soát phía máy chủ). Để trống để dùng giá trị IP được phép. Hỗ trợ lọc theo cổng và giao thức tùy chọn. Xem tài liệu để hiểu cú pháp.",
"downloadPng": "Tải PNG",
"copyPng": "Sao chép PNG"
},
"dialog": {
"change": "Thay đổi",
"cancel": "Hủy",
"create": "Tạo"
},
"toast": {
"success": "Thành công",
"saved": "Đã lưu",
"error": "Lỗi",
"unknown": "Lỗi không xác định. Xem console để biết thêm chi tiết"
},
"form": {
"actions": "Thao tác",
"save": "Lưu",
"revert": "Hoàn tác",
"sectionGeneral": "Chung",
"sectionAdvanced": "Nâng cao",
"noItems": "Không có mục nào",
"nullNoItems": "Không có mục nào. Sử dụng cấu hình chung",
"add": "Thêm"
},
"admin": {
"general": {
"sessionTimeout": "Thời gian hết phiên",
"sessionTimeoutDesc": "Thời lượng phiên cho tính năng Duy trì đăng nhập (giây)",
"metrics": "Metrics",
"metricsPassword": "Mật khẩu",
"metricsPasswordDesc": "Mật khẩu Bearer cho đường dẫn metrics (mật khẩu hoặc hash argon2)",
"json": "JSON",
"jsonDesc": "Đường dẫn metrics định dạng JSON",
"prometheus": "Prometheus",
"prometheusDesc": "Đường dẫn metrics Prometheus"
},
"config": {
"connection": "Kết nối",
"hostDesc": "Tên miền công khai mà người dùng sẽ kết nối tới (làm mất hiệu lực cấu hình)",
"portDesc": "Cổng UDP công khai mà người dùng sẽ kết nối tới (làm mất hiệu lực cấu hình, bạn cũng cần thay đổi cổng giao diện mạng)",
"allowedIpsDesc": "Các IP được cho phép mà người dùng sẽ sử dụng (cấu hình chung)",
"dnsDesc": "Máy chủ DNS mà người dùng sẽ sử dụng (cấu hình chung)",
"mtuDesc": "MTU mà người dùng sẽ sử dụng (chỉ áp dụng cho người dùng mới)",
"persistentKeepaliveDesc": "Khoảng thời gian (giây) gửi keepalive đến máy chủ. 0 = tắt (chỉ áp dụng cho người dùng mới)",
"suggest": "Gợi ý",
"suggestDesc": "Chọn địa chỉ IP hoặc tên miền cho trường Host"
},
"interface": {
"cidrSuccess": "Đã thay đổi CIDR",
"device": "Card mạng",
"deviceDesc": "Card mạng mà lưu lượng WireGuard sẽ được chuyển tiếp qua",
"mtuDesc": "MTU mà WireGuard sẽ sử dụng",
"portDesc": "Cổng UDP mà WireGuard sẽ sử dụng (bạn cũng cần thay đổi cổng cấu hình)",
"changeCidr": "Thay đổi CIDR",
"restart": "Khởi động lại giao diện mạng",
"restartDesc": "Khởi động lại giao diện mạng WireGuard",
"restartWarn": "Bạn có chắc muốn khởi động lại giao diện mạng? Điều này sẽ ngắt kết nối tất cả người dùng.",
"restartSuccess": "Đã khởi động lại giao diện mạng",
"firewall": "Lọc lưu lượng",
"firewallEnabled": "Bật tường lửa theo từng người dùng",
"firewallEnabledDesc": "Áp dụng iptables để giới hạn người dùng chỉ truy cập các IP đích xác định. Sau khi kích hoạt, cho phép cấu hình điểm đến riêng cho từng người dùng."
},
"introText": "Chào mừng đến bảng quản trị.\n\nTại đây bạn có thể quản lý cài đặt chung, cấu hình, cài đặt giao diện mạng và hooks.\n\nBắt đầu bằng cách chọn một trong các mục trong thanh bên."
},
"zod": {
"generic": {
"required": "{0} không được để trống",
"validNumber": "{0} phải là số hợp lệ",
"validNumberRange": "{0} phải là số hoặc khoảng số hợp lệ",
"validString": "{0} phải là chuỗi hợp lệ",
"validBoolean": "{0} phải là giá trị boolean hợp lệ",
"validArray": "{0} phải là mảng hợp lệ",
"stringMin": "{0} phải có ít nhất {1} ký tự",
"numberMin": "{0} phải có giá trị ít nhất là {1}"
},
"client": {
"id": "ID thiết bị",
"name": "Tên",
"expiresAt": "Hết hạn lúc",
"address4": "Địa chỉ IPv4",
"address6": "Địa chỉ IPv6",
"serverAllowedIps": "IP được phép phía máy chủ",
"firewallIps": "IP được phép qua tường lửa",
"firewallIpsInvalid": "IP tường lửa không hợp lệ. Xem tài liệu để biết cú pháp được hỗ trợ."
},
"user": {
"username": "Tên đăng nhập",
"password": "Mật khẩu",
"remember": "Ghi nhớ",
"name": "Tên",
"email": "Email",
"emailInvalid": "Email phải có định dạng hợp lệ",
"passwordMatch": "Mật khẩu phải khớp nhau",
"totpEnable": "Bật TOTP",
"totpEnableTrue": "Bật TOTP phải là true",
"totpCode": "Mã TOTP"
},
"userConfig": {
"host": "Host"
},
"general": {
"sessionTimeout": "Thời gian hết phiên",
"metricsEnabled": "Số liệu",
"metricsPassword": "Mật khẩu số liệu"
},
"interface": {
"cidr": "CIDR",
"device": "Thiết bị mạng",
"cidrValid": "CIDR phải hợp lệ"
},
"otl": "Liên kết dùng một lần",
"stringMalformed": "Chuỗi không đúng định dạng",
"body": "Body phải là đối tượng hợp lệ",
"hook": "Hook",
"enabled": "Đã bật",
"mtu": "MTU",
"port": "Cổng",
"persistentKeepalive": "Persistent Keepalive",
"address": "Địa chỉ IP",
"dns": "DNS",
"allowedIps": "Các IP được phép",
"file": "Tệp"
},
"hooks": {
"preUp": "PreUp",
"postUp": "PostUp",
"preDown": "PreDown",
"postDown": "PostDown"
},
"copy": {
"notSupported": "Không hỗ trợ sao chép",
"copied": "Đã sao chép!",
"failed": "Sao chép thất bại",
"copy": "Sao chép"
},
"awg": {
"jCLabel": "Số lượng gói tin rác (Jc)",
"jCDescription": "Số gói tin rác cần gửi (1-128, khuyến nghị: 4-12)",
"jMinLabel": "Kích thước tối thiểu gói tin rác (Jmin)",
"jMinDescription": "Kích thước tối thiểu của gói tin rác (0-1279*, khuyến nghị: 8, phải nhỏ hơn Jmax)",
"jMaxLabel": "Kích thước tối đa gói tin rác (Jmax)",
"jMaxDescription": "Kích thước tối đa của gói tin rác (1-1280*, khuyến nghị: 80, phải lớn hơn Jmin)",
"s1Label": "Kích thước rác gói tin khởi tạo (S1)",
"s1Description": "Kích thước rác gói tin khởi tạo (0-1132[1280* - 148 = 1132], khuyến nghị: 15-150, S1+56 ≠ S2)",
"s2Label": "Kích thước rác gói tin phản hồi (S2)",
"s2Description": "Kích thước rác gói tin phản hồi (0-1188[1280* - 92 = 1188], khuyến nghị: 15-150)",
"s3Label": "Kích thước rác gói tin cookie reply (S3)",
"s3Description": "Kích thước rác gói tin cookie reply",
"s4Label": "Kích thước rác gói tin vận chuyển (S4)",
"s4Description": "Kích thước rác gói tin vận chuyển",
"h1Label": "Header khởi tạo (H1)",
"h1Description": "Giá trị hoặc khoảng header gói tin khởi tạo (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
"h2Label": "Header phản hồi (H2)",
"h2Description": "Giá trị hoặc khoảng header gói tin phản hồi (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
"h3Label": "Header cookie reply (H3)",
"h3Description": "Giá trị hoặc khoảng header gói tin cookie reply (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
"h4Label": "Header vận chuyển (H4)",
"h4Description": "Giá trị hoặc khoảng header gói tin vận chuyển (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
"i1Label": "Gói tin rác đặc biệt 1 (I1)",
"i1Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
"i2Label": "Gói tin rác đặc biệt 2 (I2)",
"i2Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
"i3Label": "Gói tin rác đặc biệt 3 (I3)",
"i3Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
"i4Label": "Gói tin rác đặc biệt 4 (I4)",
"i4Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
"i5Label": "Gói tin rác đặc biệt 5 (I5)",
"i5Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
"mtuNote": "Các giá trị phụ thuộc vào MTU",
"obfuscationParameters": "Tham số làm rối AmneziaWG"
}
}

View file

@ -136,6 +136,11 @@ export default defineNuxtConfig({
language: 'gl-ES',
name: 'Galego',
},
{
code: 'vi',
language: 'vi-VN',
name: 'Tiếng Việt',
},
],
defaultLocale: 'en',
vueI18n: './i18n.config.ts',