mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
feat(i18n): improve Lao (lo) language support (#13313)
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/Русский-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
@@ -2,6 +2,7 @@ package dto
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
)
|
||||
@@ -133,6 +134,7 @@ type Locale struct {
|
||||
Tr string `json:"tr"`
|
||||
Es string `json:"es-es" yaml:"es-es"`
|
||||
Fa string `json:"fa"`
|
||||
Lo string `json:"lo"`
|
||||
}
|
||||
|
||||
type AppForm struct {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
ErrInvalidParams: 'ຄຳຮ້ອງຂໍບໍ່ຖືກຕ້ອງ: {{ .detail }}'
|
||||
ErrMcpGatewayArgsParse: 'ຮູບແບບອາກິວເມັນ MCP ກຳນົດເອງບໍ່ຖືກຕ້ອງ'
|
||||
ErrMcpGatewayArgsConflict: 'ອາກິວເມັນ {{ .name }} ຖືກຈັດການໂດຍ 1Panel ແລະ ບໍ່ສາມາດຕັ້ງຄ່າໃນອາກິວເມັນກຳນົດເອງໄດ້'
|
||||
ErrTokenParse: 'ໂທເຄັນຜິດພາດ: {{ .detail }}'
|
||||
ErrInitialPassword: 'ລະຫັດຜ່ານເດີມບໍ່ຖືກຕ້ອງ'
|
||||
ErrInternalServer: 'ລະບົບພາຍໃນຜິດພາດ: {{ .detail }}'
|
||||
@@ -10,6 +12,11 @@ ErrWgetProxyNotConfigured: 'ກະລຸນາກຳນົດຄ່າເຊີ
|
||||
ErrWgetProxyInvalid: 'ທີ່ຢູ່ເຊີເວີພຣັອກຊີບໍ່ຖືກຕ້ອງ: {{ .detail }}'
|
||||
ErrRecordExist: 'ຂໍ້ມູນນີ້ມີຢູ່ໃນລະບົບແລ້ວ'
|
||||
ErrRecordNotFound: 'ບໍ່ພົບຂໍ້ມູນ'
|
||||
WafLogExport: 'ສົ່ງອອກລັອກ WAF'
|
||||
MonitorLogExport: 'ສົ່ງອອກລັອກການຕິດຕາມເວັບໄຊ'
|
||||
LogExportNoData: 'ບໍ່ມີລັອກທີ່ກົງກັບເງື່ອນໄຂການກັ່ນຕອງ'
|
||||
LogExportDiskSpace: 'ພື້ນທີ່ດິສກ໌ທີ່ໃຊ້ໄດ້ໜ້ອຍກວ່າ 1 GiB; ການສົ່ງອອກຖືກຢຸດແລ້ວ'
|
||||
LogExportRetentionInvalid: 'ໄລຍະເກັບບັນທຶກການສົ່ງອອກຕ້ອງຢູ່ລະຫວ່າງ 1 ຫາ 30 ມື້'
|
||||
ErrStructTransform: 'ການແປງປະເພດຂໍ້ມູນລົ້ມເຫຼວ: {{ .err }}'
|
||||
ErrNotLogin: 'ຍັງບໍ່ໄດ້ເຂົ້າສູ່ລະບົບ: {{ .detail }}'
|
||||
ErrPasswordExpired: 'ລະຫັດຜ່ານໝົດອາຍຸ: {{ .detail }}'
|
||||
@@ -48,6 +55,7 @@ Decrypt: "ຖອດລະຫັດ"
|
||||
#agent
|
||||
ErrAgentAccountBound: 'ບັນຊີຖືກຜູກມັດກັບຕົວແທນ (Agent) ແລະບໍ່ສາມາດລຶບໄດ້'
|
||||
ErrTerminalAIAccountInUse: 'ບັນຊີໂມເດລນີ້ກຳລັງຖືກໃຊ້ໂດຍ Terminal AI. ກະລຸນາປ່ຽນບັນຊີໃນການຕັ້ງຄ່າ Terminal AI ຫຼື ປິດໃຊ້ງານ Terminal AI ແລ້ວລອງໃໝ່.'
|
||||
ErrFileAIAccountInUse: 'ບັນຊີໂມເດລນີ້ກຳລັງຖືກໃຊ້ໂດຍ AI ຈັດການໄຟລ໌. ກະລຸນາປ່ຽນບັນຊີໃນການຕັ້ງຄ່າ AI ຈັດການໄຟລ໌ ຫຼື ປິດໃຊ້ງານແລ້ວລອງໃໝ່.'
|
||||
ErrAgentAccountUnavailable: 'ການເຊື່ອມຕໍ່ບັນຊີບໍ່ສາມາດໃຊ້ງານໄດ້: {{ .err }}'
|
||||
ErrAgentProviderNotSupported: 'ບໍ່ຮອງຮັບຜູ້ໃຫ້ບໍລິການຕົວແທນນີ້'
|
||||
ErrAgentAccountRequired: 'ກະລຸນາເລືອກບັນຊີຕົວແທນກ່ອນ'
|
||||
@@ -55,6 +63,7 @@ ErrAgentAccountNotVerified: 'ບັນຊີຕົວແທນຍັງບໍ່
|
||||
ErrAgentAccountModelsRequired: 'ກະລຸນາກຳນົດຄ່າໂມເດລຢ່າງໜ້ອຍໜຶ່ງຕົວ'
|
||||
ErrAgentAccountSingleInitialModel: 'ສາມາດກຳນົດຄ່າໂມເດລເລີ່ມຕົ້ນໄດ້ພຽງຕົວດຽວໃນລະຫວ່າງການສ້າງບັນຊີ'
|
||||
ErrAgentModelNotInAccount: 'ໂມເດລບໍ່ໄດ້ຖືກກຳນົດຄ່າໃນບັນຊີທີ່ເລືອກ'
|
||||
ErrAgentVerifyModelInUse: 'ໂມເດລນີ້ຖືກໃຊ້ສຳລັບກວດສອບບັນຊີ. ກະລຸນາເລືອກໂມເດລກວດສອບອື່ນກ່ອນລຶບ.'
|
||||
ErrAgentFallbackModelDuplicate: 'ໂມເດລສຳຮອງ (Fallback) ບໍ່ສາມາດຊ້ຳກັນໄດ້'
|
||||
ErrAgentFallbackModelPrimary: 'ໂມເດລສຳຮອງບໍ່ສາມາດຄືກັນກັບໂມເດລຫຼັກ'
|
||||
ErrAgentModelInUse: 'ຕົວແທນທີ່ຜູກມັດກຳລັງໃຊ້ໂມເດລນີ້ຢູ່: {{ .name }}'
|
||||
@@ -362,6 +371,9 @@ ErrParseIP: 'ຮູບແບບ IP ບໍ່ຖືກຕ້ອງ'
|
||||
ErrDefaultIP: 'ຊື່ default ຖືກສະຫງວນໄວ້; ກະລຸນາໃຊ້ຊື່ອື່ນ'
|
||||
ErrGroupInUse: 'ກຸ່ມ IP ກຳລັງຖືກໃຊ້ງານໂດຍກົດລະບຽບ Blacklist/Whitelist'
|
||||
ErrIPGroupAclUse: 'ກຸ່ມ IP ກຳລັງຖືກໃຊ້ງານໂດຍກົດລະບຽບປັບແຕ່ງເອງຂອງເວັບໄຊ {{ .name }}'
|
||||
ErrIPGroupOriginProtectionUse: 'ກຸ່ມ IP ຖືກໃຊ້ໂດຍການປ້ອງກັນ CDN Origin ຂອງເວັບໄຊ {{ .name }}'
|
||||
ErrOriginProtectionIPGroupRequired: 'ກະລຸນາເລືອກຢ່າງໜ້ອຍໜຶ່ງກຸ່ມ IP ທີ່ບໍ່ຫວ່າງກ່ອນເປີດການປ້ອງກັນ Origin'
|
||||
ErrOriginProtectionIPGroupInvalid: 'ກຸ່ມ IP {{ .name }} ບໍ່ມີຢູ່ ຫຼື ຫວ່າງເປົ່າ'
|
||||
ErrGroupExist: 'ຊື່ກຸ່ມ IP ມີຢູ່ໃນລະບົບແລ້ວ'
|
||||
ErrIPRange: 'ຊ່ວງ IP ບໍ່ຖືກຕ້ອງ'
|
||||
ErrIPExist: 'IP ມີຢູ່ໃນລະບົບແລ້ວ'
|
||||
|
||||
@@ -23,7 +23,7 @@ type Login struct {
|
||||
Password string `json:"password" validate:"required"`
|
||||
Captcha string `json:"captcha"`
|
||||
CaptchaID string `json:"captchaID"`
|
||||
Language string `json:"language" validate:"required,oneof=zh en 'zh-Hant' ko ja ru ms 'pt-BR' tr 'es-ES' fa"`
|
||||
Language string `json:"language" validate:"required,oneof=zh en 'zh-Hant' ko ja ru ms 'pt-BR' tr 'es-ES' fa lo"`
|
||||
}
|
||||
|
||||
type SystemSetting struct {
|
||||
|
||||
@@ -29,6 +29,7 @@ var langFiles = map[string]string{
|
||||
"tr": "lang/tr.yaml",
|
||||
"es-ES": "lang/es-ES.yaml",
|
||||
"fa": "lang/fa.yaml",
|
||||
"lo": "lang/lo.yaml",
|
||||
}
|
||||
|
||||
func GetMsgWithMap(key string, maps map[string]interface{}) string {
|
||||
|
||||
409
core/i18n/lang/lo.yaml
Normal file
409
core/i18n/lang/lo.yaml
Normal file
@@ -0,0 +1,409 @@
|
||||
# base errors
|
||||
ErrInvalidParams: "ພາລາມິເຕີຄຳຮ້ອງຂໍບໍ່ຖືກຕ້ອງ: {{ .detail }}"
|
||||
ErrTokenParse: "ເກີດຂໍ້ຜິດພາດໃນການສ້າງໂທເຄັນ: {{ .detail }}"
|
||||
ErrInitialPassword: "ລະຫັດຜ່ານເລີ່ມຕົ້ນບໍ່ຖືກຕ້ອງ"
|
||||
ErrInternalServer: "ຂໍ້ຜິດພາດພາຍໃນເຊີບເວີ: {{ .detail }}"
|
||||
ErrInternalServerKey: "ຂໍ້ຜິດພາດພາຍໃນເຊີບເວີ:"
|
||||
ErrRecordExist: "ມີບັນທຶກນີ້ຢູ່ແລ້ວ"
|
||||
ErrRecordNotFound: "ບໍ່ພົບບັນທຶກ"
|
||||
ErrStructTransform: "ການແປງຊະນິດຂໍ້ມູນລົ້ມເຫຼວ: {{ .detail }}"
|
||||
ErrNotSupportType: "ບໍ່ຮອງຮັບຊະນິດ: {{ .name }}"
|
||||
ErrDemoEnvironment: "ນີ້ແມ່ນເຊີບເວີສາທິດ, ຫ້າມດຳເນີນການນີ້!"
|
||||
ErrCmdTimeout: "ການປະຕິບັດຄຳສັ່ງໝົດເວລາ!"
|
||||
ErrPortInUsed: "ພອດ {{ .name }} ກຳລັງຖືກໃຊ້ງານຢູ່!"
|
||||
ErrFileNotFound: "ບໍ່ມີໄຟລ໌ {{ .name }}"
|
||||
ErrReqFailed: "ຄຳຮ້ອງຂໍ {{.name}} ລົ້ມເຫຼວ: {{ .err }}"
|
||||
|
||||
# request and entrance
|
||||
ErrNoSuchHost: "ການແປງຊື່ໂຮສລົ້ມເຫຼວ: {{ .err }}"
|
||||
ErrHttpReqNotFound: "ບໍ່ພົບຊັບພະຍາກອນທີ່ຮ້ອງຂໍ: {{ .err }}"
|
||||
ErrHttpReqFailed: "ຄຳຮ້ອງຂໍລົ້ມເຫຼວ {{ .err }}"
|
||||
ErrHttpReqTimeOut: "ຄຳຮ້ອງຂໍໝົດເວລາ {{ .err }}"
|
||||
ErrCreateHttpClient: "ສ້າງຄຳຮ້ອງຂໍບໍ່ສຳເລັດ {{ .err }}"
|
||||
ErrProxy: "ຄຳຮ້ອງຂໍລົ້ມເຫຼວ; ກະລຸນາກວດສອບສະຖານະຂອງໂນດນີ້: {{ .detail }}"
|
||||
ErrProxySetting: "ບໍ່ມີຂໍ້ມູນເຊີບເວີພຣັອກຊີ {{ .err }}, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrEntrance: "ຂໍ້ມູນທາງເຂົ້າຄວາມປອດໄພຜິດພາດ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrEntranceFormat: "ບໍ່ຮອງຮັບທາງເຂົ້າຄວາມປອດໄພ {{ .name }}. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່."
|
||||
|
||||
# login and security
|
||||
ErrNotLogin: "ຜູ້ໃຊ້ຍັງບໍ່ໄດ້ເຂົ້າລະບົບ: {{ .detail }}"
|
||||
ErrSessionDataNotFound: "ເຊດຊັນໝົດອາຍຸແລ້ວ"
|
||||
ErrSessionDataFormat: "ຮູບແບບຂໍ້ມູນເຊດຊັນບໍ່ຖືກຕ້ອງ"
|
||||
ErrPasswordExpired: "ລະຫັດຜ່ານໝົດອາຍຸແລ້ວ: {{ .detail }}"
|
||||
ErrLoginLocked: "ພະຍາຍາມລົ້ມເຫຼວຫຼາຍຄັ້ງເກີນໄປ. ການເຂົ້າລະບົບຖືກລັອກຊົ່ວຄາວ 5 ນາທີ."
|
||||
ErrApiConfigStatusInvalid: "ການເຂົ້າເຖິງ API ຖືກປິດໃຊ້ງານ: {{ .detail }}"
|
||||
ErrApiConfigKeyInvalid: "ຄີ API ບໍ່ຖືກຕ້ອງ: {{ .detail }}"
|
||||
ErrApiConfigIPInvalid: "IP ຂອງຄຳຮ້ອງຂໍ API ບໍ່ຢູ່ໃນລາຍຊື່ອະນຸຍາດ: {{ .detail }}"
|
||||
ErrApiConfigDisable: "ອິນເຕີເຟດນີ້ຫ້າມການເອີ້ນໃຊ້ API: {{ .detail }}"
|
||||
ErrApiConfigKeyTimeInvalid: "ເວລາປະທັບ API ບໍ່ຖືກຕ້ອງ: {{ .detail }}"
|
||||
ErrPasskeyDisabled: "Passkey ຕ້ອງເປີດໃຊ້ງານ HTTPS"
|
||||
ErrPasskeyNotConfigured: "ຍັງບໍ່ໄດ້ຕັ້ງຄ່າ Passkey"
|
||||
ErrPasskeyLimit: "ຈຳນວນ Passkey ຮອດຂີດຈຳກັດແລ້ວ (ສູງສຸດ 5)"
|
||||
ErrPasskeySession: "ເຊດຊັນ Passkey ໝົດອາຍຸ ຫຼື ບໍ່ຖືກຕ້ອງ"
|
||||
ErrPasskeyDuplicate: "ມີ Passkey ນີ້ຢູ່ແລ້ວ"
|
||||
ErrPasskeyVerify: "ການຢືນຢັນ Passkey ລົ້ມເຫຼວ"
|
||||
|
||||
# user and permission
|
||||
ErrNoSuchUser: "ບໍ່ພົບຂໍ້ມູນຜູ້ໃຊ້, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrToMaster: "ຜູ້ໃຊ້ນີ້ບໍ່ມີສິດດຳເນີນການນີ້ໃນໂນດຫຼັກ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrToNode: "ຜູ້ໃຊ້ນີ້ບໍ່ມີສິດດຳເນີນການນີ້ໃນໂນດນີ້. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrRBAC: "ສິດຂອງຜູ້ໃຊ້ບໍ່ພຽງພໍ. ບໍ່ສາມາດດຳເນີນການນີ້ໄດ້. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrNoneNode: "ຜູ້ໃຊ້ນີ້ບໍ່ມີສິດໃຊ້ງານໂນດ. ກະລຸນາຕິດຕໍ່ຜູ້ບໍລິຫານ ຫຼື ກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrOnlySuperAdmin: "ມີພຽງຜູ້ບໍລິຫານສູງສຸດເທົ່ານັ້ນທີ່ໃຊ້ຟັງຊັນນີ້ໄດ້!"
|
||||
ErrRolePresetCannotDelete: "ບໍ່ສາມາດລຶບບົດບາດທີ່ລະບົບກຳນົດໄວ້ລ່ວງໜ້າ"
|
||||
ErrRolePresetCannotUpdate: "ບໍ່ສາມາດອັບເດດບົດບາດທີ່ລະບົບກຳນົດໄວ້ລ່ວງໜ້າ"
|
||||
ErrRoleBoundToUser: "ບົດບາດນີ້ຖືກຜູກກັບຜູ້ໃຊ້ແລ້ວ ແລະ ບໍ່ສາມາດລຶບໄດ້"
|
||||
ErrRolePresetCannotBind: "ບໍ່ສາມາດມອບໝາຍບົດບາດທີ່ລະບົບກຳນົດໄວ້ລ່ວງໜ້າໃຫ້ຜູ້ໃຊ້"
|
||||
ErrNodeAdminMasterForbidden: "ບໍ່ສາມາດເພີ່ມສິດຜູ້ບໍລິຫານໂນດໃຫ້ກັບໂນດຫຼັກ"
|
||||
ErrSuperAdminCannotDelete: "ບໍ່ສາມາດລຶບຜູ້ໃຊ້ທີ່ເປັນຜູ້ບໍລິຫານສູງສຸດ"
|
||||
ErrGroupIsDefault: "ເປັນກຸ່ມເລີ່ມຕົ້ນ, ບໍ່ສາມາດລຶບໄດ້"
|
||||
ErrGroupIsInUse: "ກຸ່ມນີ້ກຳລັງຖືກໃຊ້ງານ ແລະ ບໍ່ສາມາດລຶບໄດ້."
|
||||
|
||||
# license
|
||||
LicenseCheck: 'ກວດສອບວ່າໃບອະນຸຍາດພ້ອມໃຊ້ງານຫຼືບໍ່'
|
||||
ErrLicenseInUsed: 'ໃບອະນຸຍາດຖືກຜູກໄວ້ແລ້ວ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!'
|
||||
ErrLicenseExpired: 'ໃບອະນຸຍາດໝົດອາຍຸແລ້ວ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!'
|
||||
ErrLicense: "ຮູບແບບໃບອະນຸຍາດຜິດພາດ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrLicenseCheck: "ການກວດສອບໃບອະນຸຍາດລົ້ມເຫຼວ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrXpackVersion: "ການກວດສອບໃບອະນຸຍາດລົ້ມເຫຼວ, ໃບອະນຸຍາດນີ້ຈຳກັດເວີຊັນ ແລະ ບໍ່ສາມາດນຳເຂົ້າໄດ້, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrLicenseSave: "ບັນທຶກຂໍ້ມູນໃບອະນຸຍາດບໍ່ສຳເລັດ, ຂໍ້ຜິດພາດ {{ .err }}, ກະລຸນາລອງໃໝ່!"
|
||||
ErrLicenseSync: "ການຊິງໃບອະນຸຍາດລົ້ມເຫຼວ, ບໍ່ພົບຂໍ້ມູນໃບອະນຸຍາດໃນຖານຂໍ້ມູນ!"
|
||||
ErrLicenseExist: "ມີບັນທຶກໃບອະນຸຍາດນີ້ຢູ່ແລ້ວ. ທ່ານສາມາດໄປທີ່ໜ້າໃບອະນຸຍາດເພື່ອຜູກໂນດໄດ້ໂດຍກົງ."
|
||||
ErrXpackNotFound: "ສ່ວນນີ້ຕ້ອງໃຊ້ຮຸ່ນທຸລະກິດ. ກະລຸນານຳເຂົ້າໃບອະນຸຍາດໃນ ການຕັ້ງຄ່າແຜງ > ໃບອະນຸຍາດ."
|
||||
ErrXpackExceptional: "ສ່ວນນີ້ຕ້ອງໃຊ້ຮຸ່ນທຸລະກິດ. ກະລຸນາຊິງສະຖານະໃບອະນຸຍາດໃນ ການຕັ້ງຄ່າແຜງ > ໃບອະນຸຍາດ."
|
||||
ErrXpackLost: "ການລອງໃບອະນຸຍາດໃໝ່ຮອດຂີດຈຳກັດແລ້ວ. ໄປທີ່ ການຕັ້ງຄ່າແຜງ > ໃບອະນຸຍາດ ແລະ ຊິງດ້ວຍຕົນເອງ."
|
||||
ErrEnterpriseLicenseRequired: "ຍັງບໍ່ໄດ້ນຳເຂົ້າໃບອະນຸຍາດຮຸ່ນວິສາຫະກິດ. ກະລຸນານຳເຂົ້າໃບອະນຸຍາດກ່ອນ."
|
||||
ErrDeviceLost: "ໄຟລ໌ທີ່ຈຳເປັນສຳລັບກວດສອບໃບອະນຸຍາດຫາຍໄປ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrDeviceErr: "ສະພາບແວດລ້ອມປັດຈຸບັນບໍ່ກົງກັບສະພາບແວດລ້ອມທີ່ນຳເຂົ້າໃບອະນຸຍາດ. ກະລຸນາແກ້ໄຂໃບອະນຸຍາດແລ້ວນຳເຂົ້າໃໝ່."
|
||||
ErrXpackTimeout: "ຄຳຮ້ອງຂໍໝົດເວລາ, ການເຊື່ອມຕໍ່ເຄືອຂ່າຍອາດບໍ່ສະຖຽນ, ກະລຸນາລອງໃໝ່ພາຍຫຼັງ!"
|
||||
ErrUnbindMaster: "ຍັງມີໂນດຢູ່ໃນການຈັດການໂນດ. ກະລຸນາລຶບໂນດກ່ອນ ແລ້ວຈຶ່ງຍົກເລີກການຜູກໃບອະນຸຍາດປັດຈຸບັນ."
|
||||
ErrFreeNodeLimit: "ຈຳນວນໂນດທີ່ສາມາດເພີ່ມໄດ້ຮອດຂີດຈຳກັດແລ້ວ. ກະລຸນາຊື້ແລ້ວລອງໃໝ່."
|
||||
ErrNodeBound: "ໃບອະນຸຍາດນີ້ຖືກຜູກກັບໂນດອື່ນແລ້ວ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrNodeBoundDelete: "ໃບອະນຸຍາດນີ້ຖືກຜູກແລ້ວ ແລະ ບໍ່ຮອງຮັບການລຶບ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrNodeBoundLimit: "ໂນດຟຣີປັດຈຸບັນຮອດຂີດຈຳກັດແລ້ວ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrLicenseFree: "ໂນດຟຣີຈະໃຊ້ງານໄດ້ເມື່ອໃບອະນຸຍາດຖືກຜູກກັບໂນດຢ່າງຖືກຕ້ອງເທົ່ານັ້ນ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່."
|
||||
ErrLicenseUnbind: "ຍັງມີໂນດຮຸ່ນຊຸມຊົນທີ່ຜູກກັບໃບອະນຸຍາດນີ້. ກະລຸນາຍົກເລີກການຜູກໃນ ການຕັ້ງຄ່າແຜງ > ໃບອະນຸຍາດ ແລ້ວລອງໃໝ່."
|
||||
ErrLicenseBindCount: "ຈຳນວນໂນດຟຣີຂອງໃບອະນຸຍາດໃໝ່ນ້ອຍກວ່າຈຳນວນໂນດຮຸ່ນຊຸມຊົນທີ່ຜູກຢູ່ປັດຈຸບັນ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່."
|
||||
ErrNoSuchNode: "ບໍ່ພົບຂໍ້ມູນໂນດ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrNodeUnbind: "ໂນດນີ້ບໍ່ຢູ່ໃນຂອບເຂດການຜູກຂອງໃບອະນຸຍາດ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrNodeBind: "ໂນດນີ້ຖືກຜູກກັບໃບອະນຸຍາດແລ້ວ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrNodeLocalRollback: "ໂນດຫຼັກບໍ່ຮອງຮັບການຍ້ອນກັບໂດຍກົງ. ກະລຸນາໃຊ້ຄຳສັ່ງ '1pctl restore' ດ້ວຍຕົນເອງເພື່ອຍ້ອນກັບ."
|
||||
ErrIntlLicense: "ເວີຊັນປັດຈຸບັນຍັງບໍ່ຮອງຮັບການນຳເຂົ້າໃບອະນຸຍາດສາກົນ. ກະລຸນາລໍຖ້າ!"
|
||||
InvalidRequestBodyType: "ຮູບແບບເນື້ອຫາຄຳຮ້ອງຂໍບໍ່ຖືກຕ້ອງ. ກະລຸນາກວດວ່າເນື້ອຫາກົງກັບຮູບແບບທີ່ກຳນົດແລ້ວລອງໃໝ່."
|
||||
InvalidLicenseCodeType: "ຮູບແບບລະຫັດໃບອະນຸຍາດທີ່ໃຫ້ມາບໍ່ຖືກຕ້ອງ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
LicenseNotFoundType: "ບໍ່ພົບໃບອະນຸຍາດ, ບໍ່ມີບັນທຶກທີ່ກົງກັບໃບອະນຸຍາດທີ່ໃຫ້ມາໃນລະບົບ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
LicenseRevokedType: "ໃບອະນຸຍາດທີ່ຮ້ອງຂໍຖືກຖອນແລ້ວ ແລະ ບໍ່ສາມາດໃຊ້ງານໄດ້ອີກ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
LicenseExpiredType: "ໃບອະນຸຍາດໝົດອາຍຸແລ້ວ. ກະລຸນາຕໍ່ອາຍຸ ຫຼື ນຳເຂົ້າໃໝ່ໃນ ການຕັ້ງຄ່າແຜງ - ໃບອະນຸຍາດ ກ່ອນລອງໃໝ່."
|
||||
LicenseProductMismatchType: "ໃບອະນຸຍາດບໍ່ກົງກັບຜະລິດຕະພັນ ຫຼື ບໍລິການທີ່ຮ້ອງຂໍ!"
|
||||
InvalidAssigneeType: "ຂໍ້ມູນຜູ້ໃຊ້ ຫຼື ອຸປະກອນເປົ້າໝາຍສຳລັບການມອບໝາຍໃບອະນຸຍາດບໍ່ຖືກຕ້ອງ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
LicenseUsageNotFoundType: "ບໍ່ພົບບັນທຶກການໃຊ້ງານ. ໃບອະນຸຍາດນີ້ຍັງບໍ່ໄດ້ເປີດໃຊ້ງານ ຫຼື ໃຊ້ງານເທື່ອ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
LicenseUsageLimitExceededType: "ໃບອະນຸຍາດນີ້ຖືກຜູກກັບໂນດອື່ນແລ້ວ. ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
|
||||
# node and cluster
|
||||
MasterNode: "ໂນດຫຼັກ"
|
||||
Node: "ໂນດ"
|
||||
ErrLocalDelete: "ບໍ່ສາມາດລຶບໂນດພາຍໃນເຄື່ອງໄດ້!"
|
||||
ErrMasterDelete: "ບໍ່ສາມາດລຶບໂນດຫຼັກໄດ້. ກະລຸນາລຶບໂນດຍ່ອຍກ່ອນ."
|
||||
ClusterNameIsExist: "ມີຊື່ຄລັສເຕີນີ້ຢູ່ແລ້ວ."
|
||||
AppStatusUnHealthy: "ດຶງສະຖານະແອັບບໍ່ສຳເລັດ. ກະລຸນາກວດສອບສະຖານະໂນດທີ່ຕິດຕັ້ງໃນລາຍຊື່ໂນດ."
|
||||
MasterNodePortNotAvailable: "ການກວດສອບການເຊື່ອມຕໍ່ຂອງໂນດ {{ .name }} ຜ່ານພອດ {{ .port }} ລົ້ມເຫຼວ. ກະລຸນາກວດສອບການຕັ້ງຄ່າໄຟຣ໌ວໍ/ກຸ່ມຄວາມປອດໄພ ແລະ ສະຖານະໂນດຫຼັກ."
|
||||
ClusterMasterNotExist: "ໂນດຫຼັກຂອງຄລັສເຕີຖືກຕັດການເຊື່ອມຕໍ່. ກະລຸນາລຶບໂນດຍ່ອຍ."
|
||||
|
||||
# virtual machine
|
||||
ErrVMNotFound: "ບໍ່ມີເຄື່ອງສະເໝືອນ"
|
||||
ErrVMAlreadyExists: "ມີເຄື່ອງສະເໝືອນຢູ່ແລ້ວ"
|
||||
ErrVMImageAlreadyExists: "ມີອິມເມຈເຄື່ອງສະເໝືອນຢູ່ແລ້ວ: {{ .detail }}"
|
||||
ErrVMStoragePathInUse: "ເສັ້ນທາງພູນຈັດເກັບຖືກໃຊ້ໂດຍ [{{ .name }}] ແລ້ວ"
|
||||
ErrVMHelperNotFound: "ບໍ່ພົບ 1panel-kvm"
|
||||
ErrVMBridgeManaged: "ຊື່ບຣິດຈ໌ຖືກຈັດການໂດຍ libvirt ຫຼື Docker ແລ້ວ"
|
||||
ErrVMNetworkInUse: "ເຄືອຂ່າຍກຳລັງຖືກໃຊ້ງານ ແລະ ບໍ່ສາມາດລຶບໄດ້"
|
||||
ErrVMStorageInUse: "ພູນຈັດເກັບກຳລັງຖືກໃຊ້ງານ ແລະ ບໍ່ສາມາດລຶບໄດ້"
|
||||
ErrVMStorageNameCannotChange: "ບໍ່ສາມາດປ່ຽນຊື່ພູນຈັດເກັບໄດ້"
|
||||
ErrVMStoragePathCannotChange: "ບໍ່ສາມາດປ່ຽນເສັ້ນທາງພູນຈັດເກັບໄດ້"
|
||||
ErrVMRunning: "ເຄື່ອງສະເໝືອນກຳລັງເຮັດວຽກ"
|
||||
ErrVMLibvirtConnect: "ເຊື່ອມຕໍ່ກັບ libvirt ບໍ່ສຳເລັດ"
|
||||
ErrVMPermission: "ບໍ່ມີສິດດຳເນີນການກັບເຄື່ອງສະເໝືອນ: {{ .detail }}"
|
||||
ErrVMNetworkNotFound: "ບໍ່ມີເຄືອຂ່າຍເຄື່ອງສະເໝືອນ"
|
||||
ErrVMInvalidPath: "ເສັ້ນທາງເຄື່ອງສະເໝືອນບໍ່ຖືກຕ້ອງ"
|
||||
ErrVMInvalidInput: "ພາລາມິເຕີເຄື່ອງສະເໝືອນບໍ່ຖືກຕ້ອງ"
|
||||
ErrVMCommandFailed: "ຄຳສັ່ງເຄື່ອງສະເໝືອນລົ້ມເຫຼວ: {{ .err }}"
|
||||
VMCreateTask: "ສ້າງເຄື່ອງສະເໝືອນ [{{ .name }}]"
|
||||
VMCreateFromTemplateTask: "ສ້າງເຄື່ອງສະເໝືອນ [{{ .name }}] ຈາກແມ່ແບບ"
|
||||
VMUpdateTask: "ອັບເດດເຄື່ອງສະເໝືອນ [{{ .name }}]"
|
||||
VMRenameTask: "ປ່ຽນຊື່ເຄື່ອງສະເໝືອນ [{{ .name }}] ເປັນ [{{ .newName }}]"
|
||||
VMDeleteTask: "ລຶບເຄື່ອງສະເໝືອນ [{{ .name }}]"
|
||||
VMTemplateCreateTask: "ບັນທຶກເຄື່ອງສະເໝືອນ [{{ .name }}] ເປັນແມ່ແບບ [{{ .template }}]"
|
||||
VMTemplateDeleteTask: "ລຶບແມ່ແບບເຄື່ອງສະເໝືອນ [{{ .name }}]"
|
||||
VMForceDeleteMetadataOnly: "ບໍ່ພົບ 1panel-kvm, ຈະບັງຄັບລຶບສະເພາະເມຕາດາຕາຂອງເຄື່ອງສະເໝືອນ [{{ .name }}]"
|
||||
VMForceDeleteMetadataAfterLibvirtFailed: "ລຶບເຄື່ອງສະເໝືອນ [{{ .name }}] ຈາກ libvirt ບໍ່ສຳເລັດ, ຈະບັງຄັບລຶບເມຕາດາຕາ: {{ .err }}"
|
||||
VMForceDeleteDiskFailed: "ບັງຄັບລຶບໄຟລ໌ດິສກ໌ເຄື່ອງສະເໝືອນ [{{ .path }}] ບໍ່ສຳເລັດ: {{ .err }}"
|
||||
VMForceDeleteDiskSuccess: "ບັງຄັບລຶບໄຟລ໌ດິສກ໌ເຄື່ອງສະເໝືອນ [{{ .path }}] ສຳເລັດແລ້ວ"
|
||||
VMSnapshotCreateTask: "ສ້າງສະແນັບຊັອດ [{{ .snapshot }}] ໃຫ້ເຄື່ອງສະເໝືອນ [{{ .vm }}]"
|
||||
VMSnapshotCreateStep: "ສ້າງສະແນັບຊັອດເຄື່ອງສະເໝືອນ [{{ .snapshot }}]"
|
||||
VMSnapshotRecoverTask: "ກູ້ຄືນສະແນັບຊັອດ [{{ .snapshot }}] ໃຫ້ເຄື່ອງສະເໝືອນ [{{ .vm }}]"
|
||||
VMSnapshotRecoverStep: "ກູ້ຄືນສະແນັບຊັອດເຄື່ອງສະເໝືອນ [{{ .snapshot }}]"
|
||||
VMSnapshotDeleteTask: "ລຶບສະແນັບຊັອດ [{{ .snapshot }}] ຂອງເຄື່ອງສະເໝືອນ [{{ .vm }}]"
|
||||
VMSnapshotDeleteStep: "ລຶບສະແນັບຊັອດເຄື່ອງສະເໝືອນ [{{ .snapshot }}]"
|
||||
|
||||
# app
|
||||
CustomAppStoreFileValid: "ແພັກເກດຮ້ານຄ້າແອັບຕ້ອງເປັນຮູບແບບ .tar.gz"
|
||||
AppBackup: 'ສຳຮອງແອັບ'
|
||||
AppBackupPush: 'ໂອນໄຟລ໌ສຳຮອງແອັບ {{.file}} ໄປຫາໂນດ {{ .name }}'
|
||||
ErrSourceTargetSame: 'ໂນດຕົ້ນທາງ ແລະ ໂນດປາຍທາງຈະເປັນໂນດດຽວກັນບໍ່ໄດ້!'
|
||||
AppInstall: 'ຕິດຕັ້ງແອັບ {{ .name }} ໃນໂນດ {{ .targetNode }}'
|
||||
AppInstallCheck: 'ກວດສອບສະພາບແວດລ້ອມສຳລັບຕິດຕັ້ງແອັບ'
|
||||
|
||||
# backup
|
||||
ErrBackupInUsed: "ບັນຊີສຳຮອງນີ້ຖືກໃຊ້ໃນວຽກຕາມກຳນົດເວລາ ແລະ ບໍ່ສາມາດລຶບໄດ້"
|
||||
ErrBackupCheck: "ການທົດສອບການເຊື່ອມຕໍ່ບັນຊີສຳຮອງລົ້ມເຫຼວ {{ .err }}"
|
||||
ErrBackupLocal: "ບັນຊີສຳຮອງເຊີບເວີພາຍໃນເຄື່ອງບໍ່ຮອງຮັບການດຳເນີນການນີ້!"
|
||||
ErrBackupPublic: "ກວດພົບວ່າບັນຊີສຳຮອງນີ້ບໍ່ແມ່ນບັນຊີສາທາລະນະ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
ErrOSSConn: "ບໍ່ສາມາດຮັບເວີຊັນລ່າສຸດໄດ້. ກະລຸນາກວດສອບການເຊື່ອມຕໍ່ອິນເຕີເນັດຂອງເຊີບເວີ."
|
||||
MvBackup: "ຍ້າຍຂໍ້ມູນໄປຫາໄດເຣັກທໍຣີສຳຮອງ"
|
||||
|
||||
# alert
|
||||
ErrAlertSync: "ການຊິງຂໍ້ມູນແຈ້ງເຕືອນຜິດພາດ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
|
||||
# AI gateway
|
||||
ErrAIProxyUserGroupIsDefault: "ບໍ່ສາມາດລຶບກຸ່ມຜູ້ໃຊ້ເລີ່ມຕົ້ນໄດ້."
|
||||
ErrAIProxyUserGroupInUse: "ກຸ່ມຜູ້ໃຊ້ກຳລັງຖືກໃຊ້ງານ ແລະ ບໍ່ສາມາດລຶບໄດ້."
|
||||
ErrAIProxyUserGroupExists: "ມີຊື່ກຸ່ມຜູ້ໃຊ້ນີ້ຢູ່ແລ້ວ."
|
||||
ErrAIProxyBackendAccountExists: "ບັນຊີໂມເດວນີ້ຖືກນຳເຂົ້າໃນພູນບັນຊີ AI Gateway ແລ້ວ."
|
||||
ErrAIProxyModelGroupInUse: "ກຸ່ມໂມເດວກຳລັງຖືກໃຊ້ງານ ແລະ ບໍ່ສາມາດລຶບໄດ້."
|
||||
ErrAIProxyModelGroupExists: "ມີຊື່ກຸ່ມໂມເດວນີ້ຢູ່ແລ້ວ."
|
||||
ErrAIProxySensitiveGroupInUse: "ກຸ່ມຄຳທີ່ລະອຽດອ່ອນກຳລັງຖືກໃຊ້ງານ ແລະ ບໍ່ສາມາດລຶບໄດ້."
|
||||
ErrAIProxySensitiveGroupExists: "ມີຊື່ກຸ່ມຄຳທີ່ລະອຽດອ່ອນນີ້ຢູ່ແລ້ວ."
|
||||
AIBenchmarkRun: "ດຳເນີນການທົດສອບປະສິດທິພາບ AI"
|
||||
|
||||
# task
|
||||
TaskStart: "ວຽກ {{ .name }} ເລີ່ມແລ້ວ [START]"
|
||||
TaskEnd: "ວຽກ {{ .name }} ສິ້ນສຸດແລ້ວ [COMPLETED]"
|
||||
TaskFailed: "ວຽກ {{ .name }} ລົ້ມເຫຼວ"
|
||||
TaskTimeout: "ວຽກ {{ .name }} ໝົດເວລາ"
|
||||
TaskSuccess: "ວຽກ {{ .name }} ສຳເລັດ"
|
||||
TaskRetry: "ລອງວຽກ {{ .name }} ໃໝ່"
|
||||
SubTaskSuccess: "{{ .name }} ສຳເລັດ"
|
||||
SubTaskFailed: "{{ .name }} ລົ້ມເຫຼວ: {{ .err }}"
|
||||
TaskInstall: "ຕິດຕັ້ງ"
|
||||
TaskUpgrade: "ອັບເກຣດ"
|
||||
TaskSync: 'ຊິງຂໍ້ມູນ'
|
||||
TaskSyncForNode: "ຊິງຂໍ້ມູນໂນດ"
|
||||
TaskBackup: "ສຳຮອງ"
|
||||
TaskPush: "ສົ່ງ"
|
||||
TaskRsync: "ຊິງຂໍ້ມູນ"
|
||||
SuccessStatus: "{{ .name }} ສຳເລັດ"
|
||||
FailedStatus: "{{ .name }} ລົ້ມເຫຼວ {{ .err }}"
|
||||
Start: "ເລີ່ມ"
|
||||
SubTask: "ວຽກຍ່ອຍ"
|
||||
Skip: "ບໍ່ສົນໃຈຂໍ້ຜິດພາດ ແລະ ສືບຕໍ່"
|
||||
Success: "ສຳເລັດ"
|
||||
|
||||
# agent batch task
|
||||
BatchInstallAgent: "ຕິດຕັ້ງເອເຈນແບບກຸ່ມ"
|
||||
DispatchAgentInstallTasks: "ຈັດສົ່ງວຽກຕິດຕັ້ງເອເຈນ"
|
||||
BatchUpgradeAgent: "ອັບເກຣດເອເຈນແບບກຸ່ມ"
|
||||
DispatchAgentUpgradeTasks: "ຈັດສົ່ງວຽກອັບເກຣດເອເຈນ"
|
||||
BatchAgentInstallDispatchFailed: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຕິດຕັ້ງ {{ .agentType }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchAgentInstallSubmitted: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຕິດຕັ້ງ {{ .agentType }} ສຳເລັດແລ້ວ!"
|
||||
BatchAgentUpgradeDispatchFailed: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກອັບເກຣດ {{ .agentType }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchAgentUpgradeAlreadyLatest: "ໂນດ {{ .node }} ມີເອເຈນ {{ .agent }} ຢູ່ທີ່ເວີຊັນເປົ້າໝາຍແລ້ວ, ຂ້າມ"
|
||||
BatchAgentUpgradeSubmitted: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກອັບເກຣດ {{ .agent }} ສຳເລັດແລ້ວ!"
|
||||
BatchAgentUpgradeFailed: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກອັບເກຣດ {{ .agent }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchInstallAgentSkill: "ແຈກຢາຍ Skill ແບບກຸ່ມ"
|
||||
DispatchAgentSkillInstallTasks: "ຈັດສົ່ງວຽກຕິດຕັ້ງ Skill"
|
||||
BatchAgentSkillDispatchFailed: "ໂນດ {{ .node }} ຈັດສົ່ງ {{ .skill }} ໄປຫາ {{ .target }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchAgentNoAgentsFound: "ໂນດ {{ .node }} ບໍ່ພົບເອເຈນ {{ .agentType }}, ຂ້າມ"
|
||||
BatchAgentSkillSkipped: "ໂນດ {{ .node }} {{ .agent }} ຖືກຂ້າມ ຂໍ້ຄວາມ: {{ .msg }}"
|
||||
BatchAgentSkillInstallSubmitted: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຕິດຕັ້ງ {{ .skill }} ໄປຫາ {{ .agent }} ສຳເລັດແລ້ວ!"
|
||||
BatchAgentSkillInstallFailed: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຕິດຕັ້ງ {{ .skill }} ໄປຫາ {{ .agent }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchAgentOperateDispatchFailed: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຂອງ {{ .agentType }} ສຳລັບການດຳເນີນການ {{ .operate }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchAgentOperateSkipped: "ໂນດ {{ .node }} {{ .agent }} ຖືກຂ້າມ ຂໍ້ຄວາມ: {{ .msg }}"
|
||||
BatchAgentOperateSubmitted: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຂອງ {{ .agent }} ສຳລັບການດຳເນີນການ {{ .operate }} ສຳເລັດແລ້ວ!"
|
||||
BatchAgentOperateFailed: "ໂນດ {{ .node }} ຈັດສົ່ງວຽກຂອງ {{ .agent }} ສຳລັບການດຳເນີນການ {{ .operate }} ບໍ່ສຳເລັດ ຂໍ້ຄວາມ: {{ .err }}"
|
||||
BatchStartAgent: "ເລີ່ມເອເຈນແບບກຸ່ມ"
|
||||
DispatchAgentStartTasks: "ຈັດສົ່ງວຽກເລີ່ມເອເຈນ"
|
||||
BatchStopAgent: "ຢຸດເອເຈນແບບກຸ່ມ"
|
||||
DispatchAgentStopTasks: "ຈັດສົ່ງວຽກຢຸດເອເຈນ"
|
||||
BatchRestartAgent: "ເລີ່ມເອເຈນຄືນໃໝ່ແບບກຸ່ມ"
|
||||
DispatchAgentRestartTasks: "ຈັດສົ່ງວຽກເລີ່ມເອເຈນຄືນໃໝ່"
|
||||
BatchDeleteAgent: "ລຶບເອເຈນແບບກຸ່ມ"
|
||||
DispatchAgentDeleteTasks: "ຈັດສົ່ງວຽກລຶບເອເຈນ"
|
||||
AgentOperateStart: "ເລີ່ມ"
|
||||
AgentOperateStop: "ຢຸດ"
|
||||
AgentOperateRestart: "ເລີ່ມຄືນໃໝ່"
|
||||
AgentOperateDelete: "ລຶບ"
|
||||
|
||||
# app and skill task
|
||||
PushAppInstallTaskToNode: "ສົ່ງວຽກຕິດຕັ້ງແອັບໄປຫາໂນດ [{{ .name }}]"
|
||||
AppInstallTask: "ວຽກຕິດຕັ້ງແອັບ"
|
||||
PushAppFailed: "ສົ່ງວຽກຕິດຕັ້ງແອັບບໍ່ສຳເລັດ"
|
||||
SkillHubInstallTask: "ຕິດຕັ້ງ Skill [{{ .name }}]"
|
||||
SkillHubInstallToTarget: "ຕິດຕັ້ງ Skill ໄປຍັງເປົ້າໝາຍ [{{ .name }}]"
|
||||
|
||||
# script library
|
||||
ScriptLibrary: "ຄັງສະຄຣິບ"
|
||||
RemoteScriptLibrary: "ຄັງສະຄຣິບໄລຍະໄກ"
|
||||
ScriptSyncSkip: "ຄັງສະຄຣິບເປັນເວີຊັນລ່າສຸດແລ້ວ"
|
||||
DownloadData: "ກຳລັງດາວໂຫຼດໄຟລ໌ຄັງສະຄຣິບ data.yaml"
|
||||
DownloadPackage: "ກຳລັງດາວໂຫຼດແພັກເກດຄັງສະຄຣິບ"
|
||||
AnalyticCompletion: "ວິເຄາະສຳເລັດແລ້ວ, ກຳລັງຊິງໄປຫາຖານຂໍ້ມູນ..."
|
||||
|
||||
# node sync
|
||||
SyncNode: "ຊິງຂໍ້ມູນໄປຫາໂນດ {{ .name }}"
|
||||
LocalName: "ຊື່ 'local' ໃຊ້ສະເພາະສຳລັບການລະບຸເຄື່ອງພາຍໃນຂອງລະບົບ"
|
||||
SyncPackageData: "ຈັດແພັກເກດຂໍ້ມູນສຳລັບຊິງ"
|
||||
SyncPackageEncrypt: "ເຂົ້າລະຫັດແພັກເກດຂໍ້ມູນ"
|
||||
SyncRequest: "ຮ້ອງຂໍ API ຊິງໂນດ"
|
||||
SyncFailedRetry: "ການຊິງຂໍ້ມູນໂນດໝົດເວລາ (ຄັ້ງທີ {{ .index }}), ກຳລັງລອງໃໝ່..."
|
||||
SyncFailed: "ການຊິງລົ້ມເຫຼວ, ກະລຸນາຊິງດ້ວຍຕົນເອງໃນລາຍຊື່ໂນດ!"
|
||||
SyncSystemProxy: "ການຕັ້ງຄ່າພຣັອກຊີລະບົບ"
|
||||
SyncScripts: "ຄັງສະຄຣິບ"
|
||||
SyncBackupAccounts: "ບັນຊີສຳຮອງ"
|
||||
SyncAlertSetting: "ການຕັ້ງຄ່າແຈ້ງເຕືອນ"
|
||||
SyncCustomApp: "ແອັບກຳນົດເອງ"
|
||||
SyncLanguage: "ພາສາລະບົບ"
|
||||
SyncEdition: "ພາກພື້ນ"
|
||||
|
||||
# node upgrade
|
||||
NodeUpgrade: "ອັບເກຣດໂນດ {{ .name }}"
|
||||
UpgradeCheck: "ກວດສອບອັບເດດຂອງໂນດ"
|
||||
UpgradeCheckLocal: "ໂນດພາຍໃນເຄື່ອງບໍ່ຮອງຮັບການອັບເກຣດແບບກຸ່ມ, ຂ້າມ..."
|
||||
UpgradeCheckLatest: "ໂນດເປັນເວີຊັນລ່າສຸດແລ້ວ, ຂ້າມ..."
|
||||
NewSSHClient: "ກຳລັງເລີ່ມຕົ້ນການເຊື່ອມຕໍ່ SSH"
|
||||
BackupBeforeUpgrade: "ສຳຮອງຂໍ້ມູນກ່ອນອັບເກຣດ"
|
||||
UploadUpgradeFile: "ແຈກຢາຍໄຟລ໌ອັບເກຣດ"
|
||||
RestartAfterUpgrade: "ເລີ່ມບໍລິການຫຼັງການອັບເກຣດ"
|
||||
LoadAutoUpgradeNodesFailed: "ໂຫຼດໂນດທີ່ອັບເກຣດອັດຕະໂນມັດບໍ່ສຳເລັດ, ຂໍ້ຜິດພາດ: {{ .err }}"
|
||||
AutoUpgradeNodes: "ໂນດທີ່ອັບເກຣດອັດຕະໂນມັດ: {{ .nodes }}"
|
||||
UpdateAutoUpgradeNodesStatusFailed: "ອັບເດດສະຖານະໂນດທີ່ອັບເກຣດອັດຕະໂນມັດບໍ່ສຳເລັດ, ຂໍ້ຜິດພາດ: {{ .err }}"
|
||||
|
||||
# node add
|
||||
MasterData: "ຂໍ້ມູນໂນດຫຼັກ"
|
||||
LoadSftpClient: "ໂຫຼດໄຄລເອນ SFTP"
|
||||
PackageMasterData: "ສ້າງແພັກເກດສຳຮອງໂນດຫຼັກ"
|
||||
UploadBackup: "ອັບໂຫຼດຂໍ້ມູນສຳຮອງ"
|
||||
TaskAddNode: "ເພີ່ມໂນດ"
|
||||
LoadNodeArch: "ຮັບຂໍ້ມູນສະຖາປັດຕະຍະກຳຂອງໂນດ"
|
||||
LoadNodeArchDetail: "ກວດພົບສະຖາປັດຕະຍະກຳໂນດຫຼັກ: {{ .local }}, ສະຖາປັດຕະຍະກຳໂນດຍ່ອຍ: {{ .node }}"
|
||||
LoadNodeUpgradeDetail: "ກຳລັງໃຊ້ໄດເຣັກທໍຣີການຕິດຕັ້ງເກົ່າຂອງເວີຊັນ v1: {{ .baseDir }}, ພອດຮັບຟັງຂອງບໍລິການ: {{ .port }}"
|
||||
SyncAgentBaseInfo: "ຊິງຂໍ້ມູນພື້ນຖານຂອງໂນດ"
|
||||
GenerateSSLInfo: "ສ້າງຂໍ້ມູນ SSL ຂອງໂນດ"
|
||||
ConnInfoNotMatch: "ຂໍ້ມູນການເຊື່ອມຕໍ່ບໍ່ກົງກັນ"
|
||||
MakeAgentPackage: "ສ້າງແພັກເກດຕິດຕັ້ງໂນດ"
|
||||
SendAgent: "ແຈກຢາຍແພັກເກດຕິດຕັ້ງໂນດ"
|
||||
StartService: "ເລີ່ມບໍລິການ"
|
||||
NoBackupNode: "ໂນດສຳຮອງຫວ່າງເປົ່າ. ກະລຸນາເລືອກແລ້ວບັນທຶກກ່ອນ"
|
||||
|
||||
# node file and image sync
|
||||
LocalNodeIpFailed: "ຮັບ IP ຂອງໂນດຫຼັກບໍ່ສຳເລັດ. ກະລຸນາແກ້ໄຂໂນດຫຼັກ ແລະ ເພີ່ມທີ່ຢູ່ IP ພ້ອມຂໍ້ມູນການຢືນຢັນ SSH."
|
||||
HandlePrivateKey: "ປະມວນຜົນກະແຈສ່ວນຕົວຂອງໂນດ"
|
||||
HandlePublicKey: "ປະມວນຜົນກະແຈສາທາລະນະຂອງໂນດ"
|
||||
ExchangeFile: "ເລີ່ມຊິງ {{ .sourcePath }} ຈາກໂນດ {{ .source }} ໄປຫາໂນດ {{ .dest }}:{{ .destPath }}"
|
||||
NodeFile: "ໄຟລ໌ໂນດ"
|
||||
ImageSyncTaskName: "ຊິງອິມເມຈ {{ .count }} ລາຍການ"
|
||||
SSLSyncTaskName: "ຊິງໃບຮັບຮອງ {{ .count }} ລາຍການ"
|
||||
AppSyncTaskName: "ຊິງແອັບ {{ .name }}"
|
||||
SSLSyncToNode: "ສົ່ງໃບຮັບຮອງ [{{ .cert }}] ໄປຫາໂນດ [{{ .node }}]"
|
||||
ImageSyncSave: "ບັນທຶກອິມເມຈ {{ .image }}"
|
||||
ImageSyncSaveTags: "ບັນທຶກແທັກອິມເມຈ {{ .tags }}"
|
||||
ImageSyncToNode: "ຊິງອິມເມຈ {{ .image }} ໄປຫາໂນດ {{ .node }}"
|
||||
ImageSyncLoad: "ໂຫຼດອິມເມຈ {{ .image }} ໃນໂນດ {{ .node }}"
|
||||
ImageSyncClean: "ລ້າງໄຟລ໌ຊົ່ວຄາວຂອງອິມເມຈ {{ .image }}"
|
||||
ImageSyncNoTag: "ອິມເມຈ {{ .image }} ບໍ່ມີແທັກ ແລະ ຈະຖືກບັນທຶກດ້ວຍ ID ອິມເມຈ"
|
||||
ImageSyncFrontendTagsIgnored: "ບໍ່ພົບແທັກຂອງອິມເມຈ {{ .image }} ໃນໂນດຕົ້ນທາງ. ແທັກຈາກສ່ວນໜ້າຖືກຂ້າມ."
|
||||
ImageSyncHandlePrivateKey: "ປະມວນຜົນກະແຈສ່ວນຕົວຂອງໂນດສຳລັບຊິງອິມເມຈ"
|
||||
ImageSyncHandlePublicKey: "ປະມວນຜົນກະແຈສາທາລະນະຂອງໂນດສຳລັບຊິງອິມເມຈ"
|
||||
ImageSyncTransfer: "ເລີ່ມໂອນໄຟລ໌ຊົ່ວຄາວຂອງອິມເມຈ: {{ .source }}:{{ .sourcePath }} -> {{ .dest }}:{{ .destPath }}"
|
||||
|
||||
# command line
|
||||
SudoHelper: "ໃຊ້ {{ .cmd }} ຫຼື ປ່ຽນໄປໃຊ້ຜູ້ໃຊ້ root"
|
||||
UsernameNeed: "ຮຸ່ນວິສາຫະກິດຕ້ອງລະບຸ --username"
|
||||
DBConnErr: "ຂໍ້ຜິດພາດ: ເລີ່ມຕົ້ນການເຊື່ອມຕໍ່ຖານຂໍ້ມູນບໍ່ສຳເລັດ, {{ .err }}"
|
||||
SystemVersion: "ເວີຊັນ: "
|
||||
SystemMode: "ໂໝດ: "
|
||||
|
||||
# command line - app
|
||||
AppVersion: "ເວີຊັນແອັບ"
|
||||
AppCommands: "ຄຳສັ່ງທີ່ກ່ຽວກັບແອັບ"
|
||||
AppInit: "ເລີ່ມຕົ້ນແອັບ"
|
||||
AppKeyVal: "ຄີແອັບ (ຮອງຮັບສະເພາະພາສາອັງກິດ)"
|
||||
AppCreateFileErr: "ສ້າງໄຟລ໌ {{ .name }} ບໍ່ສຳເລັດ {{ .err }}"
|
||||
AppCreateDirErr: "ສ້າງໂຟນເດີ {{ .name }} ບໍ່ສຳເລັດ {{ .err }}"
|
||||
AppMissKey: "ບໍ່ມີຄີແອັບ, ໃຊ້ -k ເພື່ອລະບຸ"
|
||||
AppMissVersion: "ບໍ່ມີເວີຊັນແອັບ, ໃຊ້ -v ເພື່ອລະບຸ"
|
||||
AppVersionExist: "ມີເວີຊັນນີ້ຢູ່ແລ້ວ!"
|
||||
AppCreateSuccessful: "ສ້າງສຳເລັດແລ້ວ!"
|
||||
AppWriteErr: "ຂຽນໄຟລ໌ {{ .name }} ບໍ່ສຳເລັດ {{ .err }}"
|
||||
|
||||
# command line - listen IP
|
||||
ListenIPCommands: "ປ່ຽນ IP ທີ່ຮັບຟັງ"
|
||||
ListenIPv4: "ຮັບຟັງຜ່ານ IPv4"
|
||||
ListenIPv6: "ຮັບຟັງຜ່ານ IPv6"
|
||||
ListenChangeSuccessful: "ປ່ຽນສຳເລັດແລ້ວ! ຕອນນີ້ກຳລັງຮັບຟັງຢູ່ {{ .value }}"
|
||||
|
||||
# command line - reset
|
||||
ResetCommands: "ຕັ້ງຄ່າຂໍ້ມູນລະບົບຄືນໃໝ່"
|
||||
ResetMFA: "ຍົກເລີກການຢືນຢັນສອງຂັ້ນຕອນຂອງ 1Panel"
|
||||
ResetHttps: "ຍົກເລີກການເຂົ້າລະບົບ 1Panel ຜ່ານ HTTPS"
|
||||
ResetEntrance: "ຍົກເລີກທາງເຂົ້າຄວາມປອດໄພຂອງ 1Panel"
|
||||
ResetIPs: "ຍົກເລີກຂໍ້ຈຳກັດ IP ທີ່ອະນຸຍາດຂອງ 1Panel"
|
||||
ResetDomain: "ຍົກເລີກການຜູກໂດເມນຂອງ 1Panel"
|
||||
ResetPasskey: "ລ້າງ Passkey ຂອງ 1Panel"
|
||||
|
||||
# command line - user
|
||||
UserList: "ຮັບລາຍຊື່ຜູ້ໃຊ້ 1Panel"
|
||||
UserTableName: "ຊື່"
|
||||
UserTableMFAStatus: "ສະຖານະ MFA"
|
||||
UserTableSuperAdmin: "ຜູ້ບໍລິຫານສູງສຸດ"
|
||||
UserTableCreatedAt: "ສ້າງເມື່ອ"
|
||||
UserEmptyList: "ບໍ່ພົບຜູ້ໃຊ້"
|
||||
UserInfo: "ຮັບຂໍ້ມູນແຜງ"
|
||||
UserInfoAddr: "ທີ່ຢູ່ແຜງ: "
|
||||
UserInfoPassHelp: "ຄຳແນະນຳ: ເພື່ອປ່ຽນລະຫັດຜ່ານ ທ່ານສາມາດໃຊ້ຄຳສັ່ງ: "
|
||||
|
||||
# command line - restore
|
||||
RestoreCommands: "ຍ້ອນບໍລິການ ແລະ ຂໍ້ມູນ 1Panel ກັບຄືນ"
|
||||
RestoreNoSuchFile: "ບໍ່ພົບໄຟລ໌ສຳລັບຍ້ອນກັບ"
|
||||
RestoreStep1: "(1/5) ກຳລັງເລີ່ມຍ້ອນບໍລິການ ແລະ ຂໍ້ມູນ 1Panel ຈາກໄດເຣັກທໍຣີ {{ .name }}..."
|
||||
RestoreStep2: "(2/5) ຍ້ອນໄບນາຣີ 1Panel ສຳເລັດແລ້ວ"
|
||||
RestoreStep3: "(3/5) ຍ້ອນສະຄຣິບ 1Panel ສຳເລັດແລ້ວ"
|
||||
RestoreStep4: "(4/5) ຍ້ອນບໍລິການ 1Panel ສຳເລັດແລ້ວ"
|
||||
RestoreStep5: "(5/5) ຍ້ອນຂໍ້ມູນ 1Panel ສຳເລັດແລ້ວ"
|
||||
RestoreSuccessful: "ການຍ້ອນກັບສຳເລັດແລ້ວ. ກັບໄປຫາເວີຊັນ {{ .version }}. ກຳລັງເລີ່ມບໍລິການຄືນໃໝ່..."
|
||||
|
||||
# command line - update
|
||||
UpdateCommands: "ອັບເດດຂໍ້ມູນແຜງ"
|
||||
UpdateUser: "ອັບເດດຂໍ້ມູນຜູ້ໃຊ້"
|
||||
UpdatePassword: "ອັບເດດລະຫັດຜ່ານຜູ້ໃຊ້"
|
||||
UpdatePort: "ອັບເດດພອດແຜງ"
|
||||
UpdateUserNull: "ຂໍ້ຜິດພາດ: ຊື່ຜູ້ໃຊ້ຫວ່າງເປົ່າ!"
|
||||
UpdateUserBlank: "ຂໍ້ຜິດພາດ: ຊື່ຜູ້ໃຊ້ມີຊ່ອງຫວ່າງ!"
|
||||
UpdateUserFormat: "ຂໍ້ຜິດພາດ: ຮູບແບບຊື່ຜູ້ໃຊ້ບໍ່ຖືກຕ້ອງ! ຮອງຮັບສະເພາະຕົວອັກສອນອັງກິດ, ຈີນ, ຕົວເລກ ແລະ _, ຄວາມຍາວ 3-30 ຕົວ"
|
||||
UpdateUserErr: "ຂໍ້ຜິດພາດ: ອັບເດດຜູ້ໃຊ້ບໍ່ສຳເລັດ, {{ .err }}"
|
||||
UpdateSuccessful: "ອັບເດດສຳເລັດແລ້ວ!"
|
||||
UpdateUserResult: "ຜູ້ໃຊ້: {{ .name }}"
|
||||
UpdatePasswordRead: "ຂໍ້ຜິດພາດ: ອ່ານຂໍ້ມູນລະຫັດຜ່ານຜູ້ໃຊ້ບໍ່ສຳເລັດ, {{ .err }}"
|
||||
UpdatePasswordNull: "ຂໍ້ຜິດພາດ: ລະຫັດຜ່ານຜູ້ໃຊ້ຫວ່າງເປົ່າ!"
|
||||
UpdateUPasswordBlank: "ຂໍ້ຜິດພາດ: ລະຫັດຜ່ານຜູ້ໃຊ້ມີຊ່ອງຫວ່າງ!"
|
||||
UpdatePasswordFormat: "ຂໍ້ຜິດພາດ: ລະຫັດຜ່ານຜູ້ໃຊ້ຮອງຮັບສະເພາະຕົວອັກສອນ, ຕົວເລກ ແລະ ອັກຂະລະພິເສດ (!@#$%*_,.?), ຄວາມຍາວ 8-30 ຕົວ."
|
||||
UpdatePasswordLen: "ຂໍ້ຜິດພາດ: ກະລຸນາປ້ອນລະຫັດຜ່ານທີ່ຍາວກວ່າ 6 ຕົວ"
|
||||
UpdatePasswordRe: "ຢືນຢັນລະຫັດຜ່ານ:"
|
||||
UpdatePasswordErr: "ຂໍ້ຜິດພາດ: ອັບເດດລະຫັດຜ່ານຜູ້ໃຊ້ບໍ່ສຳເລັດ, {{ .err }}"
|
||||
UpdatePasswordSame: "ຂໍ້ຜິດພາດ: ລະຫັດຜ່ານສອງຄັ້ງບໍ່ກົງກັນ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
UpdatePasswordResult: "ລະຫັດຜ່ານຜູ້ໃຊ້: {{ .name }}"
|
||||
UpdatePortFormat: "ຂໍ້ຜິດພາດ: ໝາຍເລກພອດທີ່ປ້ອນຕ້ອງຢູ່ລະຫວ່າງ 1 ຫາ 65535!"
|
||||
UpdatePortUsed: "ຂໍ້ຜິດພາດ: ໝາຍເລກພອດກຳລັງຖືກໃຊ້ງານ, ກະລຸນາກວດສອບແລ້ວລອງໃໝ່!"
|
||||
UpdatePortErr: "ຂໍ້ຜິດພາດ: ອັບເດດພອດແຜງບໍ່ສຳເລັດ, {{ .err }}"
|
||||
UpdatePortResult: "ພອດແຜງ: {{ .name }}"
|
||||
UpdatePortFirewallAdd: "ເພີ່ມກົດພອດໄຟຣ໌ວໍບໍ່ສຳເລັດ, {{ .err }}, ກະລຸນາເພີ່ມພອດ {{ .name }} ເຂົ້າໃນກົດໄຟຣ໌ວໍດ້ວຍຕົນເອງ."
|
||||
UpdatePortFirewallDel: "ຂໍ້ຜິດພາດ: ລຶບພອດໄຟຣ໌ວໍບໍ່ສຳເລັດ, {{ .err }}"
|
||||
UpdatePortFirewallReload: "ໂຫຼດໄຟຣ໌ວໍຄືນໃໝ່ບໍ່ສຳເລັດ, {{ .err }}, ກະລຸນາໂຫຼດໄຟຣ໌ວໍຄືນໃໝ່ດ້ວຍຕົນເອງ."
|
||||
|
||||
# mobile app
|
||||
ErrVerifyToken: 'ການກວດສອບໂທເຄັນລົ້ມເຫຼວ. ກະລຸນາຕັ້ງຄ່າຄືນໃໝ່ແລ້ວສະແກນອີກຄັ້ງ.'
|
||||
ErrInvalidToken: 'ໂທເຄັນບໍ່ຖືກຕ້ອງ. ກະລຸນາຕັ້ງຄ່າຄືນໃໝ່ແລ້ວສະແກນອີກຄັ້ງ.'
|
||||
ErrExpiredToken: 'ໂທເຄັນໝົດອາຍຸແລ້ວ. ກະລຸນາຕັ້ງຄ່າຄືນໃໝ່ແລ້ວສະແກນອີກຄັ້ງ.'
|
||||
|
||||
# command export
|
||||
Name: "ຊື່"
|
||||
Command: "ຄຳສັ່ງ"
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/Русский-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
117
docs/README.lo.md
Normal file
117
docs/README.lo.md
Normal file
@@ -0,0 +1,117 @@
|
||||
<p align="center"><a href="https://1panel.pro"><img src="https://resource.1panel.pro/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
||||
|
||||
<h3 align="center">ແຜງຄວບຄຸມ VPS ແບບໂອເພນຊອດ ພ້ອມການຮອງຮັບເອເຈນ AI ໃນຕົວ</h3>
|
||||
|
||||
<p align="center">
|
||||
ໄດ້ຮັບຄວາມໄວ້ວາງໃຈຈາກຜູ້ໃຊ້ໂຮສເອງຫຼາຍກວ່າ <strong>2,000,000</strong> ຄົນທົ່ວໂລກ
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/2462" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2462" alt="1Panel-dev%2F1Panel | Trendshift" style="width: 240px; height: auto;" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel?color=%231890FF" alt="ໃບອະນຸຍາດ: GPL v3"></a>
|
||||
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
||||
<a href="https://discord.gg/bUpUqWqdRr"><img src="https://img.shields.io/discord/1318846410149335080?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb" alt="Discord"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="ລຸ້ນທີ່ເຜີຍແຜ່ໃນ GitHub"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="ດາວ"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="/README.md"><img alt="English" src="https://img.shields.io/badge/English-d9d9d9"></a>
|
||||
<a href="/docs/README.zh-Hans.md"><img alt="中文(简体)" src="https://img.shields.io/badge/中文(简体)-d9d9d9"></a>
|
||||
<a href="/docs/README.ja.md"><img alt="日本語" src="https://img.shields.io/badge/日本語-d9d9d9"></a>
|
||||
<a href="/docs/README.pt-br.md"><img alt="Português (Brasil)" src="https://img.shields.io/badge/Português (Brasil)-d9d9d9"></a>
|
||||
<a href="/docs/README.ar.md"><img alt="العربية" src="https://img.shields.io/badge/العربية-d9d9d9"></a>
|
||||
<a href="/docs/README.de.md"><img alt="Deutsch" src="https://img.shields.io/badge/Deutsch-d9d9d9"></a>
|
||||
<a href="/docs/README.es-es.md"><img alt="Español" src="https://img.shields.io/badge/Español-d9d9d9"></a>
|
||||
<a href="/docs/README.fr.md"><img alt="français" src="https://img.shields.io/badge/français-d9d9d9"></a>
|
||||
<a href="/docs/README.ko.md"><img alt="한국어" src="https://img.shields.io/badge/한국어-d9d9d9"></a>
|
||||
<a href="/docs/README.id.md"><img alt="Bahasa Indonesia" src="https://img.shields.io/badge/Bahasa Indonesia-d9d9d9"></a>
|
||||
<a href="/docs/README.zh-Hant.md"><img alt="中文(繁體)" src="https://img.shields.io/badge/中文(繁體)-d9d9d9"></a>
|
||||
<a href="/docs/README.tr.md"><img alt="Türkçe" src="https://img.shields.io/badge/Türkçe-d9d9d9"></a>
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/Русский-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 1Panel ແມ່ນຫຍັງ?
|
||||
|
||||
1Panel ແມ່ນແຜງຄວບຄຸມ VPS ທີ່ທັນສະໄໝ ແລະ ເປັນໂອເພນຊອດ — ພ້ອມທັງເປັນແຜງດຽວທີ່ມີ **ການຮອງຮັບເອເຈນ AI ໃນຕົວ**. ທ່ານສາມາດໃຊ້ງານໂມເດວ Ollama, ນຳໃຊ້ເອເຈນສ່ວນຕົວ OpenClaw ແລະ ຈັດການລະບົບເຊີບເວີທັງໝົດຜ່ານໜ້າເວັບທີ່ສະອາດຕາ. ບໍ່ຕ້ອງຈື່ຄຳສັ່ງ CLI.
|
||||
|
||||
👉 ເບິ່ງ [ວິດີໂອແນະນຳ 2 ນາທີ](https://www.youtube.com/watch?v=Jl_wqp-XA08)
|
||||
|
||||
## ເປັນຫຍັງຕ້ອງເລືອກ 1Panel?
|
||||
|
||||
| | 1Panel | cPanel / Plesk | aaPanel | Webmin |
|
||||
|--|--------|----------------|---------|--------|
|
||||
| ຟຣີ ແລະ ເປັນໂອເພນຊອດ | ✅ | ❌ | ບາງສ່ວນ | ✅ |
|
||||
| ຮັນໄທມ໌ເອເຈນ AI ໃນຕົວ | ✅ | ❌ | ❌ | ❌ |
|
||||
| ຕະຫຼາດແອັບແບບຄລິກດຽວ | ✅ 165+ ແອັບ | ❌ | ✅ | ❌ |
|
||||
| UI ທັນສະໄໝ (ຫຼັງປີ 2020) | ✅ | ❌ | ບາງສ່ວນ | ❌ |
|
||||
| ການຈັດການ Docker / ຄອນເທນເນີ | ✅ | ❌ | ❌ | ❌ |
|
||||
| ພັດທະນາຢ່າງຕໍ່ເນື່ອງ | ✅ | ✅ | ✅ | ຊ້າ |
|
||||
|
||||
## ຄຸນສົມບັດຫຼັກ
|
||||
|
||||
- **ຮັນໄທມ໌ເອເຈນ AI**: ນຳໃຊ້ໂມເດວ LLM ຂອງ Ollama, ເປີດໃຊ້ເອເຈນສ່ວນຕົວ OpenClaw ແລະ ຕິດຕາມການໃຊ້ GPU — ທັງໝົດເຮັດໄດ້ຈາກແດຊບອດ. ບໍ່ຕ້ອງຈັດການສະແຕັກ AI ແຍກຕ່າງຫາກ.
|
||||
- **ນຳໃຊ້ເວັບໄຊດ້ວຍຄລິກດຽວ**: ເປີດໃຊ້ເວັບໄຊທີ່ພ້ອມສຳລັບການຜະລິດ ພ້ອມການຜູກໂດເມນອັດຕະໂນມັດ, ການອອກໃບຮັບຮອງ SSL ແລະ ການຕັ້ງຄ່າ Nginx — ບໍ່ຕ້ອງຕັ້ງຄ່າດ້ວຍຕົນເອງ.
|
||||
- **ຕະຫຼາດແອັບ**: ມີແອັບໂອເພນຊອດທີ່ໜ້າເຊື່ອຖືຫຼາຍກວ່າ 165 ແອັບ (Nextcloud, Bitwarden, Umami, NocoBase ແລະ ອື່ນໆ) ທີ່ສາມາດຕິດຕັ້ງ ແລະ ອັບເດດໄດ້ດ້ວຍຄລິກດຽວ.
|
||||
- **ການຈັດການ Docker ແລະ ຄອນເທນເນີ**: ສ້າງ, ເລີ່ມ, ຢຸດ ແລະ ກວດສອບຄອນເທນເນີ, ອິມເມຈ, ເຄືອຂ່າຍ ແລະ ໂວລຸມ ຜ່ານ UI ແບບກຣາຟິກ — ບໍ່ຕ້ອງສະຫຼັບໄປມາໃນ CLI.
|
||||
- **ຄວາມປອດໄພພ້ອມໃຊ້ງານ**: ກົດໄຟຣ໌ວໍ, fail2ban, ການແຍກຄອນເທນເນີ, WAF ແລະ ບັນທຶກການກວດສອບ — ທຸກຢ່າງຖືກຕັ້ງຄ່າ ແລະ ເຮັດວຽກຕັ້ງແຕ່ມື້ທຳອິດ.
|
||||
- **ສຳຮອງ ແລະ ກູ້ຄືນ**: ກຳນົດເວລາສຳຮອງອັດຕະໂນມັດໄປຫາ AWS S3, Cloudflare R2 ຫຼື ບ່ອນຈັດເກັບພາຍໃນເຄື່ອງ. ກູ້ຄືນສະແນັບຊັອດໃດກໍໄດ້ດ້ວຍຄລິກດຽວ.
|
||||
|
||||
## ເລີ່ມຕົ້ນຢ່າງໄວ
|
||||
|
||||
> **ຄວາມຕ້ອງການ:** Linux VPS (Debian / Ubuntu / CentOS / Rocky), RAM 1 GB ແລະ ການເຊື່ອມຕໍ່ອິນເຕີເນັດ.
|
||||
> ໃຊ້ເວລາປະມານ 60 ວິນາທີ.
|
||||
|
||||
```bash
|
||||
bash -c "$(curl -sSL https://resource.1panel.pro/v2/quick_start.sh)"
|
||||
```
|
||||
|
||||
ຫຼັງຈາກຕິດຕັ້ງແລ້ວ, ເປີດ `http://<your-server-ip>:<port>/<security-path>` ໃນເບຣົາເຊີ.
|
||||
ໃຊ້ຄຳສັ່ງ `1pctl user-info` ຜ່ານ SSH ຫາກຕ້ອງການເບິ່ງຂໍ້ມູນສຳລັບເຂົ້າລະບົບ.
|
||||
|
||||
## ພາບໜ້າຈໍ
|
||||
|
||||

|
||||
|
||||
## ຮຸ່ນ Pro
|
||||
|
||||
1Panel OSS ໃຊ້ງານໄດ້ຟຣີຕະຫຼອດໄປ. ຮຸ່ນ Pro ເພີ່ມຄຸນສົມບັດທີ່ອອກແບບສຳລັບທີມ ແລະ ວຽກລະດັບການຜະລິດ:
|
||||
|
||||
| ຄຸນສົມບັດ | OSS | Pro |
|
||||
|---------|:---:|:---:|
|
||||
| ຕິດຕັ້ງແອັບດ້ວຍຄລິກດຽວ | ✅ | ✅ |
|
||||
| ເອເຈນ AI (OpenClaw) | 1 ເອເຈນ | ບໍ່ຈຳກັດ |
|
||||
| WAF ແລະ ຄວາມປອດໄພຂັ້ນສູງ | ພື້ນຖານ | ✅ |
|
||||
| ປ້ອງກັນການດັດແປງເວັບໄຊ | ❌ | ✅ |
|
||||
| ຕິດຕາມເວລາພ້ອມໃຊ້ງານຂອງເວັບໄຊ | ❌ | ✅ |
|
||||
| ການຈັດການຫຼາຍໂນດ | ❌ | ✅ |
|
||||
| ໂລໂກ້ ແລະ ຮູບແບບການສະແດງຜົນກຳນົດເອງ | ❌ | ✅ |
|
||||
| ການຊ່ວຍເຫຼືອລຳດັບຕົ້ນ | ❌ | ✅ |
|
||||
|
||||
**ເລີ່ມຕົ້ນທີ່ $80/ປີ.** [ປຽບທຽບແຜນ ແລະ ເລີ່ມທົດລອງຟຣີ 30 ມື້ →](https://1panel.pro/pricing)
|
||||
|
||||
## ປະຫວັດດາວ
|
||||
|
||||
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
||||
|
||||
## ຊຸມຊົນ ແລະ ການຊ່ວຍເຫຼືອ
|
||||
|
||||
- **Discord** — [ເຂົ້າຮ່ວມຊຸມຊົນ](https://discord.gg/bUpUqWqdRr) ເພື່ອຂໍຄວາມຊ່ວຍເຫຼືອ, ສະເໜີຄຸນສົມບັດ ແລະ ແບ່ງປັນຜົນງານ
|
||||
- **ເອກະສານ** — [1panel.pro/docs](https://1panel.pro/docs)
|
||||
- **ບັນຫາ** — [GitHub Issues](https://github.com/1Panel-dev/1Panel/issues) ສຳລັບລາຍງານບັກ
|
||||
|
||||
## ຄວາມປອດໄພ
|
||||
|
||||
ພົບຊ່ອງໂຫວ່ບໍ? ກະລຸນາອ່ານ [SECURITY.md](/SECURITY.md) ກ່ອນເຜີຍແຜ່ຂໍ້ມູນ.
|
||||
|
||||
## ໃບອະນຸຍາດ
|
||||
|
||||
ໂຄງການນີ້ໃຊ້ [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
[](https://www.bilibili.com/video/BV1Mt421n7LZ/)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-d9d9d9"></a>
|
||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||
</p>
|
||||
|
||||
[](https://www.bilibili.com/video/BV1Mt421n7LZ/)
|
||||
|
||||
@@ -1,78 +1,120 @@
|
||||
# Translation Contribution Guide
|
||||
|
||||
Thank you for your interest in helping translate 1Panel into a new language! This guide walks through every file you need to create or modify to add full language support across the frontend and backend.
|
||||
Thank you for helping translate 1Panel! A complete locale touches the frontend,
|
||||
the Core service, the Agent service, application-store metadata, and the project
|
||||
README files. This guide lists the repository changes and validation required
|
||||
before opening a pull request.
|
||||
|
||||
> **Reference PR:** [WIP: Dev v2 spanish (#10352)](https://github.com/1Panel-dev/1Panel/pull/10352) — a merged, real-world example of adding a brand-new locale (Spanish `es-ES`).
|
||||
> **Reference pull requests**
|
||||
>
|
||||
> - [WIP: Dev v2 spanish (#10352)](https://github.com/1Panel-dev/1Panel/pull/10352)
|
||||
> is a full-locale example for Spanish (`es-ES`).
|
||||
> - [docs: add Persian README (#13132)](https://github.com/1Panel-dev/1Panel/pull/13132)
|
||||
> is a localized-README example.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
## Scope
|
||||
|
||||
1Panel's i18n system spans two layers:
|
||||
1Panel has several independent translation surfaces:
|
||||
|
||||
| Layer | Technology | Translation format |
|
||||
| Surface | Technology | Repository format |
|
||||
|---|---|---|
|
||||
| **Frontend** (Vue 3) | `vue-i18n` + Element Plus | TypeScript (`.ts`) |
|
||||
| **Backend** (Go) | `go-i18n` / `nicksnyder/go-i18n` | YAML (`.yaml`) |
|
||||
| Frontend | Vue 3, `vue-i18n`, Element Plus | TypeScript (`.ts`) |
|
||||
| Core service | Go i18n | YAML (`.yaml`) |
|
||||
| Agent service | Go i18n | YAML (`.yaml`) |
|
||||
| Application store | API models and frontend types | Go and TypeScript |
|
||||
| Project introduction | GitHub README files | Markdown (`.md`) |
|
||||
|
||||
Adding a new language requires changes in **both** layers, as well as registering the locale in a few selector components.
|
||||
Adding only a frontend module does not provide complete locale support. Follow
|
||||
all applicable steps below and state explicitly in the pull request if a surface
|
||||
is intentionally out of scope.
|
||||
|
||||
---
|
||||
## Step 0 – Define locale identifiers
|
||||
|
||||
## Step 1 – Frontend translation file
|
||||
Choose the canonical runtime locale first. Use a
|
||||
[BCP 47](https://www.ietf.org/rfc/bcp/bcp47.txt) language tag and preserve its
|
||||
casing wherever the runtime locale is used. File names and third-party locale
|
||||
packs do not always use the same casing.
|
||||
|
||||
Copy the reference English file and translate all values.
|
||||
| Language | Runtime locale | Frontend module | Element Plus pack | Backend YAML | App-store key | README |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Simplified Chinese | `zh` | `zh.ts` | `zh-cn` | `zh.yaml` | `zh` | `README.zh-Hans.md` |
|
||||
| Traditional Chinese | `zh-Hant` | `zh-Hant.ts` | `zh-tw` | `zh-Hant.yaml` | `zh-hant` | `README.zh-Hant.md` |
|
||||
| English | `en` | `en.ts` | `en` | `en.yaml` | `en` | `README.md` |
|
||||
| Brazilian Portuguese | `pt-BR` | `pt-br.ts` | `pt-br` | `pt-BR.yaml` | `pt-br` | `README.pt-br.md` |
|
||||
| Spanish (Spain) | `es-ES` | `es-es.ts` | `es` | `es-ES.yaml` | `es-es` | `README.es-es.md` |
|
||||
| Lao | `lo` | `lo.ts` | `lo` | `lo.yaml` | `lo` | `README.lo.md` |
|
||||
|
||||
```
|
||||
frontend/src/lang/modules/en.ts → frontend/src/lang/modules/<locale>.ts
|
||||
Use lowercase for simple runtime codes (`ja`, `ko`, `lo`) and standard BCP 47
|
||||
casing for variants (`pt-BR`, `es-ES`, `zh-Hant`). Do not infer a file name from
|
||||
the runtime locale: add an explicit mapping when the casing or code differs.
|
||||
|
||||
Before editing, search for hard-coded locale collections so a newly introduced
|
||||
selector, whitelist, or compatibility map is not missed:
|
||||
|
||||
```bash
|
||||
rg "zh-Hant|pt-BR|es-ES" frontend core agent
|
||||
```
|
||||
|
||||
Replace every English string with its translation. Keep all keys, nested objects, and the `getFuLocaleMessage` call at the bottom unchanged:
|
||||
## Step 1 – Add the frontend translation module
|
||||
|
||||
Copy the English module and translate its values:
|
||||
|
||||
```text
|
||||
frontend/src/lang/modules/en.ts -> frontend/src/lang/modules/<module-name>.ts
|
||||
```
|
||||
|
||||
Keep the following unchanged unless the English source changed structurally:
|
||||
|
||||
- object keys, nesting, and TypeScript syntax;
|
||||
- interpolation placeholders such as `{0}`, `${name}`, and `{{ .detail }}`;
|
||||
- HTML tags, Markdown, URLs, product names, commands, and configuration keys;
|
||||
- the `getFuLocaleMessage` merge at the end of the file.
|
||||
|
||||
Pass the canonical runtime locale to `getFuLocaleMessage`, even when the module
|
||||
file name uses different casing:
|
||||
|
||||
```ts
|
||||
// frontend/src/lang/modules/<locale>.ts
|
||||
import { getFuLocaleMessage } from '@/lang/fu';
|
||||
|
||||
const message = {
|
||||
commons: {
|
||||
// ... translated strings
|
||||
// Translated values.
|
||||
},
|
||||
// ...
|
||||
};
|
||||
|
||||
export default {
|
||||
...getFuLocaleMessage('<locale>'),
|
||||
...getFuLocaleMessage('<runtime-locale>'),
|
||||
...message,
|
||||
};
|
||||
```
|
||||
|
||||
> **Tip:** The file is ~4 400 lines. Using a translation tool for a first pass is fine, but please review the output for accuracy and context.
|
||||
The English module evolves continuously. Copy it from the same branch as your
|
||||
change instead of relying on a fixed key count or line count. Machine
|
||||
translation can be used for a first pass, but every string must be reviewed in
|
||||
its UI context.
|
||||
|
||||
---
|
||||
## Step 2 – Register the frontend loader and FU messages
|
||||
|
||||
## Step 2 – Register the locale loader
|
||||
|
||||
Open `frontend/src/lang/index.ts` and add your locale to `LOCALE_LOADERS`:
|
||||
Add the canonical runtime locale and its module file to `LOCALE_LOADERS` in
|
||||
`frontend/src/lang/index.ts`:
|
||||
|
||||
```ts
|
||||
// frontend/src/lang/index.ts
|
||||
const LOCALE_LOADERS: Record<string, LocaleLoader> = {
|
||||
// existing entries …
|
||||
'<locale>': () => import('./modules/<locale>'),
|
||||
// Existing entries.
|
||||
'<runtime-locale>': () => import('./modules/<module-name>'),
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3 – FU component translations
|
||||
|
||||
`frontend/src/lang/fu.ts` contains translations for custom FU table/steps components. Add a new entry for your locale:
|
||||
Then add the locale to `fuLocales` in `frontend/src/lang/fu.ts`. These messages
|
||||
belong to the shared FU table and steps components and are not supplied by the
|
||||
main module:
|
||||
|
||||
```ts
|
||||
// frontend/src/lang/fu.ts
|
||||
const fuLocales: Record<string, FuLocaleMessage> = {
|
||||
// existing entries …
|
||||
'<locale>': {
|
||||
// Existing entries.
|
||||
'<runtime-locale>': {
|
||||
fu: {
|
||||
table: {
|
||||
more: '...',
|
||||
@@ -89,123 +131,326 @@ const fuLocales: Record<string, FuLocaleMessage> = {
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
## Step 3 – Register the Element Plus locale
|
||||
|
||||
## Step 4 – Element Plus component locale
|
||||
|
||||
Element Plus ships its own locale strings (used in date pickers, pagination, etc.). Import the matching locale pack and wire it into `frontend/src/App.vue`:
|
||||
Element Plus provides its own translations for date pickers, pagination,
|
||||
popovers, and other components. Import the matching pack in
|
||||
`frontend/src/App.vue`:
|
||||
|
||||
```ts
|
||||
// frontend/src/App.vue — import section
|
||||
import <varName> from 'element-plus/es/locale/lang/<ep-locale-code>';
|
||||
import localePack from 'element-plus/es/locale/lang/<element-plus-code>';
|
||||
```
|
||||
|
||||
Then add a branch in the `i18nLocale` computed property:
|
||||
Map the canonical runtime locale in the `i18nLocale` computed property:
|
||||
|
||||
```ts
|
||||
const i18nLocale = computed(() => {
|
||||
// existing branches …
|
||||
if (globalStore.language === '<locale>') return <varName>;
|
||||
return zhCn; // fallback unchanged
|
||||
// Existing mappings.
|
||||
if (globalStore.language === '<runtime-locale>') return localePack;
|
||||
return zhCn;
|
||||
});
|
||||
```
|
||||
|
||||
You can find all available Element Plus locale codes in `node_modules/element-plus/es/locale/lang/`.
|
||||
Confirm the pack exists in
|
||||
`frontend/node_modules/element-plus/es/locale/lang/`. If Element Plus does not
|
||||
provide the language, document the chosen fallback in the pull request rather
|
||||
than importing a nonexistent module.
|
||||
|
||||
---
|
||||
## Step 4 – Expose the locale in every frontend entry point
|
||||
|
||||
## Step 5 – Login page language selector
|
||||
### Login page
|
||||
|
||||
Open `frontend/src/views/login/components/login-form.vue` and add your locale label to `languageLabelMap`:
|
||||
`frontend/src/views/login/components/login-form.vue` currently renders two
|
||||
language menus for different login layouts. Add the new locale to **both menu
|
||||
blocks**, then add its native display name to `languageLabelMap`:
|
||||
|
||||
```ts
|
||||
const languageLabelMap: Record<string, string> = {
|
||||
// existing entries …
|
||||
'<locale>': '<Native language name>',
|
||||
// Existing entries.
|
||||
'<runtime-locale>': '<Native language name>',
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
Verify both login layouts manually. Updating only `languageLabelMap` changes the
|
||||
selected label but does not add a selectable menu item.
|
||||
|
||||
## Step 6 – Panel settings language selector
|
||||
### Panel settings
|
||||
|
||||
Open `frontend/src/views/setting/panel/index.vue` and add an option to `languageOptions`:
|
||||
Add the locale to `languageOptions` in
|
||||
`frontend/src/views/setting/panel/index.vue`:
|
||||
|
||||
```ts
|
||||
const languageOptions = ref([
|
||||
// existing entries …
|
||||
{ value: '<locale>', label: '<Native language name>' },
|
||||
// Existing entries.
|
||||
{ value: '<runtime-locale>', label: '<Native language name>' },
|
||||
]);
|
||||
```
|
||||
|
||||
---
|
||||
### Public share page
|
||||
|
||||
## Step 7 – Backend translation files (core & agent)
|
||||
Add the locale to `supportedLocales` in `frontend/src/views/share/index.vue`.
|
||||
This list controls browser-language recognition and the `Accept-Language`
|
||||
header used by public share requests.
|
||||
|
||||
The backend has **two** independent Go modules, each with its own YAML translation file. Copy the English reference and translate:
|
||||
|
||||
```
|
||||
core/i18n/lang/en.yaml → core/i18n/lang/<locale>.yaml (~264 lines)
|
||||
agent/i18n/lang/en.yaml → agent/i18n/lang/<locale>.yaml (~592 lines)
|
||||
```ts
|
||||
const supportedLocales = [
|
||||
// Existing entries.
|
||||
'<runtime-locale>',
|
||||
];
|
||||
```
|
||||
|
||||
YAML format example:
|
||||
### Locale-sensitive fallbacks
|
||||
|
||||
Review locale comparisons that select language-specific API fields. For
|
||||
example, operation records currently provide Chinese and English detail fields
|
||||
in `frontend/src/views/log/operation/index.vue`. Chinese runtime locales should
|
||||
use `detailZH`; every other locale should retain a visible `detailEN` fallback.
|
||||
Prefer one shared fallback branch instead of adding every non-Chinese locale to
|
||||
another hard-coded list.
|
||||
|
||||
## Step 5 – Allow the locale in the login API
|
||||
|
||||
The backend validates the language sent by the login request. Add the canonical
|
||||
runtime locale to the `Language` field's `oneof` validation tag in
|
||||
`core/app/dto/auth.go`:
|
||||
|
||||
```go
|
||||
Language string `json:"language" validate:"oneof=zh en ... <runtime-locale>"`
|
||||
```
|
||||
|
||||
Without this change, the new language can appear on the login page but the
|
||||
login request will be rejected as an invalid parameter.
|
||||
|
||||
Run `gofmt` on the Go file after editing it.
|
||||
|
||||
## Step 6 – Add and register Core translations
|
||||
|
||||
Copy the current English catalog and translate only its values:
|
||||
|
||||
```text
|
||||
core/i18n/lang/en.yaml -> core/i18n/lang/<runtime-locale>.yaml
|
||||
```
|
||||
|
||||
Preserve every YAML key and placeholder:
|
||||
|
||||
```yaml
|
||||
ErrInvalidParams: "Invalid request parameters: {{ .detail }}"
|
||||
ErrRecordExist: "Record already exists"
|
||||
# …
|
||||
ErrInvalidParams: "Translated text: {{ .detail }}"
|
||||
ErrRecordExist: "Translated text"
|
||||
```
|
||||
|
||||
---
|
||||
Register the catalog in `core/i18n/i18n.go`:
|
||||
|
||||
## Step 8 – Register backend locale in Go
|
||||
|
||||
Add your locale key and file path in both i18n registries:
|
||||
|
||||
**`core/i18n/i18n.go`**
|
||||
```go
|
||||
var langFiles = map[string]string{
|
||||
// existing entries …
|
||||
"<locale>": "lang/<locale>.yaml",
|
||||
// Existing entries.
|
||||
"<runtime-locale>": "lang/<runtime-locale>.yaml",
|
||||
}
|
||||
```
|
||||
|
||||
**`agent/i18n/i18n.go`**
|
||||
## Step 7 – Add and register Agent translations
|
||||
|
||||
Core and Agent are independent Go modules and have independent catalogs. Copy
|
||||
and translate the Agent catalog separately:
|
||||
|
||||
```text
|
||||
agent/i18n/lang/en.yaml -> agent/i18n/lang/<runtime-locale>.yaml
|
||||
```
|
||||
|
||||
Register it in `agent/i18n/i18n.go`:
|
||||
|
||||
```go
|
||||
var langFiles = map[string]string{
|
||||
// existing entries …
|
||||
"<locale>": "lang/<locale>.yaml",
|
||||
// Existing entries.
|
||||
"<runtime-locale>": "lang/<runtime-locale>.yaml",
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
Do not copy the Core YAML file into Agent: their key sets are different.
|
||||
|
||||
## Checklist
|
||||
## Step 8 – Extend application-store locale models
|
||||
|
||||
Before opening a PR, verify the following:
|
||||
Application-store names and descriptions use their own locale fields. Add the
|
||||
new field to both repository-side schemas.
|
||||
|
||||
- [ ] `frontend/src/lang/modules/<locale>.ts` created and all strings translated
|
||||
- [ ] Locale registered in `frontend/src/lang/index.ts` (`LOCALE_LOADERS`)
|
||||
- [ ] Locale entry added to `frontend/src/lang/fu.ts`
|
||||
- [ ] Element Plus locale imported and mapped in `frontend/src/App.vue`
|
||||
- [ ] Locale label added to `languageLabelMap` in `frontend/src/views/login/components/login-form.vue`
|
||||
- [ ] Locale option added to `languageOptions` in `frontend/src/views/setting/panel/index.vue`
|
||||
- [ ] `core/i18n/lang/<locale>.yaml` created
|
||||
- [ ] `agent/i18n/lang/<locale>.yaml` created
|
||||
- [ ] Locale registered in `core/i18n/i18n.go` (`langFiles`)
|
||||
- [ ] Locale registered in `agent/i18n/i18n.go` (`langFiles`)
|
||||
- [ ] Manually verified: new locale appears in the login language dropdown
|
||||
- [ ] Manually verified: new locale appears in **Settings → Panel → Language**
|
||||
- [ ] Manually verified: UI renders correctly after switching to the new locale
|
||||
In `agent/app/dto/app.go`, extend `Locale`:
|
||||
|
||||
---
|
||||
```go
|
||||
type Locale struct {
|
||||
// Existing fields.
|
||||
NewLanguage string `json:"<app-store-key>"`
|
||||
}
|
||||
```
|
||||
|
||||
## Locale code conventions
|
||||
In `frontend/src/api/interface/app.ts`, extend `Locale` with the same JSON key:
|
||||
|
||||
Use [BCP 47](https://www.ietf.org/rfc/bcp/bcp47.txt) locale codes. Examples used in this project:
|
||||
```ts
|
||||
interface Locale {
|
||||
// Existing fields.
|
||||
'<app-store-key>': string;
|
||||
}
|
||||
```
|
||||
|
||||
| Language | Locale code |
|
||||
Add the app-store key to the `description` example in
|
||||
`core/cmd/server/app/app_config.yml` as well. This embedded template is written
|
||||
when the server command scaffolds a new local application configuration.
|
||||
|
||||
Review `frontend/src/utils/app-store.ts` as well. Simple codes that lowercase to
|
||||
the same value normally need no special handling; regional or script variants
|
||||
may need an explicit runtime-locale-to-app-store-key mapping.
|
||||
|
||||
These schema changes make the repository capable of reading the locale. The
|
||||
translated application names and descriptions are maintained in the external
|
||||
application-store data source and must be coordinated separately. Until that
|
||||
data exists, the application store falls back to English.
|
||||
|
||||
## Step 9 – Add a localized README
|
||||
|
||||
Copy the root README to the documentation directory:
|
||||
|
||||
```text
|
||||
README.md -> docs/README.<readme-code>.md
|
||||
```
|
||||
|
||||
Translate prose while preserving Markdown structure, HTML, images, links,
|
||||
commands, badges, and code samples. Check every relative link from its new
|
||||
location under `docs/`; a link that works from the repository root may need a
|
||||
different relative path in the localized file.
|
||||
|
||||
Then keep the language navigation synchronized:
|
||||
|
||||
1. Add the new README link to the language badge row in `README.md`.
|
||||
2. Add the same link to every existing `docs/README.*.md` language badge row.
|
||||
3. Add the locale to the table in this guide's
|
||||
[Locale code reference](#locale-code-reference).
|
||||
|
||||
Use the native language name for the badge label. The README locale suffix may
|
||||
follow an existing documentation convention (`zh-Hans`, `pt-br`, `es-es`) and
|
||||
does not have to match the runtime locale casing.
|
||||
|
||||
## Step 10 – Format code and regenerate API documentation
|
||||
|
||||
Format every changed Go source file:
|
||||
|
||||
```bash
|
||||
gofmt -w core/app/dto/auth.go core/i18n/i18n.go
|
||||
gofmt -w agent/app/dto/app.go agent/i18n/i18n.go
|
||||
```
|
||||
|
||||
The login-language enum and application-store locale model are represented in
|
||||
generated Swagger files. Install the repository-compatible `swag` command, then
|
||||
run the generator test from the Core module:
|
||||
|
||||
```bash
|
||||
cd core
|
||||
go test ./cmd/server/docs -run TestGenerateSwaggerDoc
|
||||
```
|
||||
|
||||
This updates generated files under `core/cmd/server/docs/`. Do not edit the
|
||||
generated Swagger output by hand. If the generator is unavailable, call that
|
||||
out explicitly in the pull request instead of committing stale manual changes.
|
||||
|
||||
## Step 11 – Validate the locale
|
||||
|
||||
### Automated checks
|
||||
|
||||
Run checks from the repository root unless a command changes directory:
|
||||
|
||||
```bash
|
||||
# Frontend type checking.
|
||||
cd frontend
|
||||
npm run type-check
|
||||
|
||||
# Lint only the frontend files changed by the locale contribution.
|
||||
./node_modules/.bin/eslint \
|
||||
src/lang/modules/<module-name>.ts \
|
||||
src/lang/index.ts \
|
||||
src/lang/fu.ts \
|
||||
src/App.vue \
|
||||
src/views/login/components/login-form.vue \
|
||||
src/views/setting/panel/index.vue \
|
||||
src/views/share/index.vue \
|
||||
src/views/log/operation/index.vue \
|
||||
src/api/interface/app.ts \
|
||||
src/utils/app-store.ts
|
||||
|
||||
# Compile and test the directly affected Go packages.
|
||||
cd ../core
|
||||
go test ./i18n ./app/dto
|
||||
|
||||
cd ../agent
|
||||
go test ./i18n ./app/dto
|
||||
|
||||
# Check whitespace errors in all changed files.
|
||||
cd ..
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Also compare each translated catalog with its English source:
|
||||
|
||||
- the frontend module has the same translation keys and nesting;
|
||||
- each Core and Agent YAML file has exactly the same keys as its corresponding
|
||||
English file;
|
||||
- placeholders, formatting tokens, HTML tags, URLs, and commands are preserved;
|
||||
- YAML files parse successfully, with no duplicate keys;
|
||||
- all README links and badges resolve to the intended files.
|
||||
|
||||
### Manual checks
|
||||
|
||||
- [ ] Both login layouts show the native language name and can select it.
|
||||
- [ ] Login succeeds with the locale in the request; validation does not reject it.
|
||||
- [ ] **Settings -> Panel -> Language** can switch to the locale and retains it after reload.
|
||||
- [ ] Element Plus date, pagination, select, and confirmation components use the expected language.
|
||||
- [ ] A representative Core API error is translated.
|
||||
- [ ] A representative Agent task/error message is translated.
|
||||
- [ ] A public share page recognizes the browser locale and sends the expected `Accept-Language` value.
|
||||
- [ ] Operation-log details remain visible through the correct Chinese or English fallback.
|
||||
- [ ] Application-store metadata uses the locale when available and falls back to English when absent.
|
||||
- [ ] The localized README renders correctly and every README language badge links to it.
|
||||
- [ ] Layout, punctuation, truncation, and text direction are correct at common screen sizes.
|
||||
|
||||
For right-to-left languages, verify the login page, navigation, forms, tables,
|
||||
dialogs, and mixed-direction values such as IP addresses. RTL layout support may
|
||||
require a separate frontend change beyond translating strings.
|
||||
|
||||
## External translation resources
|
||||
|
||||
Some runtime assets are not maintained in this repository:
|
||||
|
||||
- application-store names and descriptions come from the external
|
||||
application-store data source;
|
||||
- the language shell resources downloaded as `language/lang.tar.gz` are
|
||||
published through the 1Panel resource service.
|
||||
|
||||
Repository locale support does not automatically update either resource. If the
|
||||
new language needs them, coordinate publication with the relevant maintainer and
|
||||
record the status in the pull request. Do not add generated or downloaded
|
||||
archives to this repository unless a maintainer requests it.
|
||||
|
||||
## Complete pull-request checklist
|
||||
|
||||
- [ ] Canonical runtime, module, Element Plus, app-store, and README codes are documented.
|
||||
- [ ] `frontend/src/lang/modules/<module-name>.ts` is complete and reviewed.
|
||||
- [ ] `frontend/src/lang/index.ts` contains the locale loader.
|
||||
- [ ] `frontend/src/lang/fu.ts` contains the FU messages.
|
||||
- [ ] `frontend/src/App.vue` maps an existing Element Plus locale pack or documents a fallback.
|
||||
- [ ] Both language menus and `languageLabelMap` are updated in `frontend/src/views/login/components/login-form.vue`.
|
||||
- [ ] `languageOptions` is updated in `frontend/src/views/setting/panel/index.vue`.
|
||||
- [ ] `supportedLocales` is updated in `frontend/src/views/share/index.vue`.
|
||||
- [ ] Locale-sensitive API-field fallbacks, including operation-log details, remain visible.
|
||||
- [ ] The login validator is updated in `core/app/dto/auth.go`.
|
||||
- [ ] `core/i18n/lang/<runtime-locale>.yaml` exists and is registered in `core/i18n/i18n.go`.
|
||||
- [ ] `agent/i18n/lang/<runtime-locale>.yaml` exists and is registered in `agent/i18n/i18n.go`.
|
||||
- [ ] Application-store locale fields are updated in `agent/app/dto/app.go`, `frontend/src/api/interface/app.ts`, and `core/cmd/server/app/app_config.yml`.
|
||||
- [ ] Regional or script variants are normalized in `frontend/src/utils/app-store.ts` when needed.
|
||||
- [ ] `docs/README.<readme-code>.md` exists and every README language badge is synchronized.
|
||||
- [ ] Changed Go files are formatted and Swagger output is regenerated.
|
||||
- [ ] Frontend, Core, Agent, catalog-parity, placeholder, and Markdown checks pass.
|
||||
- [ ] All applicable manual checks pass.
|
||||
- [ ] External application-store and language-resource work is completed or clearly tracked.
|
||||
|
||||
## Locale code reference
|
||||
|
||||
| Language | Runtime locale |
|
||||
|---|---|
|
||||
| Simplified Chinese | `zh` |
|
||||
| Traditional Chinese | `zh-Hant` |
|
||||
@@ -218,19 +463,12 @@ Use [BCP 47](https://www.ietf.org/rfc/bcp/bcp47.txt) locale codes. Examples used
|
||||
| Brazilian Portuguese | `pt-BR` |
|
||||
| Spanish (Spain) | `es-ES` |
|
||||
| Persian | `fa` |
|
||||
| Lao | `lo` |
|
||||
|
||||
Use lowercase for simple codes (`ja`, `ko`) and the standard BCP 47 casing for regional variants (`pt-BR`, `es-ES`, `zh-Hant`).
|
||||
## Pull-request title convention
|
||||
|
||||
**Frontend TypeScript file names** use all-lowercase with hyphens preserved exactly as they appear in the existing `frontend/src/lang/modules/` directory (e.g. `pt-br.ts`, `es-es.ts`, `zh-hant.ts`).
|
||||
|
||||
**Backend YAML file names** mirror the locale code exactly, preserving the original casing (e.g. `pt-BR.yaml`, `es-ES.yaml`, `zh-Hant.yaml`).
|
||||
|
||||
---
|
||||
|
||||
## PR title convention
|
||||
|
||||
```
|
||||
feat(i18n): add <language name> (<locale>) locale support
|
||||
```text
|
||||
feat(i18n): add <language name> (<runtime-locale>) locale support
|
||||
```
|
||||
|
||||
Example: `feat(i18n): add German (de-DE) locale support`
|
||||
|
||||
@@ -18,6 +18,7 @@ import ko from 'element-plus/es/locale/lang/ko';
|
||||
import tr from 'element-plus/es/locale/lang/tr';
|
||||
import esES from 'element-plus/es/locale/lang/es';
|
||||
import fa from 'element-plus/es/locale/lang/fa';
|
||||
import lo from 'element-plus/es/locale/lang/lo';
|
||||
import { useTheme } from '@/global/use-theme';
|
||||
useTheme();
|
||||
|
||||
@@ -38,6 +39,7 @@ const i18nLocale = computed(() => {
|
||||
if (language.value === 'tr') return tr;
|
||||
if (language.value === 'es-ES') return esES;
|
||||
if (language.value === 'fa') return fa;
|
||||
if (language.value === 'lo') return lo;
|
||||
return zhCn;
|
||||
});
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ export namespace App {
|
||||
ko: string;
|
||||
tr: string;
|
||||
'es-es': string;
|
||||
fa: string;
|
||||
lo: string;
|
||||
}
|
||||
|
||||
export interface AppDTO extends App {
|
||||
|
||||
@@ -95,8 +95,7 @@
|
||||
<pre
|
||||
v-if="showScriptPreview"
|
||||
class="vscode-open__script max-h-[430px] overflow-auto p-3 text-xs leading-6"
|
||||
>{{ scriptText }}</pre
|
||||
>
|
||||
>{{ scriptText }}</pre>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex h-full min-h-[320px] flex-col justify-between gap-4">
|
||||
|
||||
@@ -70,7 +70,7 @@ const fuLocales: Record<string, FuLocaleMessage> = {
|
||||
finish: 'ສຳເລັດ',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ms: {
|
||||
fu: {
|
||||
table: {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -63,6 +63,7 @@
|
||||
<el-dropdown-item command="ms">Bahasa Melayu</el-dropdown-item>
|
||||
<el-dropdown-item command="tr">Turkish</el-dropdown-item>
|
||||
<el-dropdown-item command="fa">فارسی</el-dropdown-item>
|
||||
<el-dropdown-item command="lo">ພາສາລາວ</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -122,6 +123,7 @@
|
||||
<el-dropdown-item command="ms">Bahasa Melayu</el-dropdown-item>
|
||||
<el-dropdown-item command="tr">Turkish</el-dropdown-item>
|
||||
<el-dropdown-item command="fa">فارسی</el-dropdown-item>
|
||||
<el-dropdown-item command="lo">ພາສາລາວ</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -389,6 +391,7 @@ const languageLabelMap: Record<string, string> = {
|
||||
tr: 'Turkish',
|
||||
'es-ES': 'España - Español',
|
||||
fa: 'فارسی',
|
||||
lo: 'ພາສາລາວ',
|
||||
};
|
||||
|
||||
const handleCommand = async (command: string) => {
|
||||
|
||||
@@ -289,6 +289,7 @@ const languageOptions = ref([
|
||||
{ value: 'tr', label: 'Turkish' },
|
||||
{ value: 'es-ES', label: 'España - Español' },
|
||||
{ value: 'fa', label: 'فارسی' },
|
||||
{ value: 'lo', label: 'ພາສາລາວ' },
|
||||
]);
|
||||
|
||||
if (isIntl.value) {
|
||||
|
||||
@@ -54,7 +54,7 @@ const initializing = ref(true);
|
||||
const errorMessage = ref('');
|
||||
const shareInfo = ref<File.FileSharePublicInfo | null>(null);
|
||||
const shareLocale = ref('en');
|
||||
const supportedLocales = ['zh', 'zh-Hant', 'en', 'pt-BR', 'ja', 'ru', 'ms', 'ko', 'tr', 'es-ES'];
|
||||
const supportedLocales = ['zh', 'zh-Hant', 'en', 'pt-BR', 'ja', 'ru', 'ms', 'ko', 'tr', 'es-ES', 'lo'];
|
||||
|
||||
const code = computed(() => String(route.params.code || '').trim());
|
||||
const currentNode = computed(() => String(route.query.operateNode || 'local'));
|
||||
|
||||
Reference in New Issue
Block a user