mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-20 05:52:24 +00:00
customizable remark #1300
This commit is contained in:
parent
35feef650f
commit
c980a06969
16 changed files with 118 additions and 22 deletions
|
@ -19,6 +19,7 @@ import (
|
||||||
type SubService struct {
|
type SubService struct {
|
||||||
address string
|
address string
|
||||||
showInfo bool
|
showInfo bool
|
||||||
|
remarkModel string
|
||||||
inboundService service.InboundService
|
inboundService service.InboundService
|
||||||
settingService service.SettingService
|
settingService service.SettingService
|
||||||
}
|
}
|
||||||
|
@ -34,6 +35,10 @@ func (s *SubService) GetSubs(subId string, host string, showInfo bool) ([]string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
s.remarkModel, err = s.settingService.GetRemarkModel()
|
||||||
|
if err != nil {
|
||||||
|
s.remarkModel = "-ieo"
|
||||||
|
}
|
||||||
for _, inbound := range inbounds {
|
for _, inbound := range inbounds {
|
||||||
clients, err := s.inboundService.GetClients(inbound)
|
clients, err := s.inboundService.GetClients(inbound)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -857,17 +862,30 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubService) genRemark(inbound *model.Inbound, email string, extra string) string {
|
func (s *SubService) genRemark(inbound *model.Inbound, email string, extra string) string {
|
||||||
var remark []string
|
separationChar := string(s.remarkModel[0])
|
||||||
|
orderChars := s.remarkModel[1:]
|
||||||
|
orders := map[byte]string{
|
||||||
|
'i': "",
|
||||||
|
'e': "",
|
||||||
|
'o': "",
|
||||||
|
}
|
||||||
if len(email) > 0 {
|
if len(email) > 0 {
|
||||||
if len(inbound.Remark) > 0 {
|
orders['e'] = email
|
||||||
remark = append(remark, inbound.Remark)
|
}
|
||||||
|
if len(inbound.Remark) > 0 {
|
||||||
|
orders['i'] = inbound.Remark
|
||||||
|
}
|
||||||
|
if len(extra) > 0 {
|
||||||
|
orders['e'] = extra
|
||||||
|
}
|
||||||
|
|
||||||
|
var remark []string
|
||||||
|
for i := 0; i < len(orderChars); i++ {
|
||||||
|
char := orderChars[i]
|
||||||
|
order, exists := orders[char]
|
||||||
|
if exists && order != "" {
|
||||||
|
remark = append(remark, order)
|
||||||
}
|
}
|
||||||
remark = append(remark, email)
|
|
||||||
if len(extra) > 0 {
|
|
||||||
remark = append(remark, extra)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return inbound.Remark
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.showInfo {
|
if s.showInfo {
|
||||||
|
@ -884,7 +902,7 @@ func (s *SubService) genRemark(inbound *model.Inbound, email string, extra strin
|
||||||
// Get remained days
|
// Get remained days
|
||||||
if statsExist {
|
if statsExist {
|
||||||
if !stats.Enable {
|
if !stats.Enable {
|
||||||
return fmt.Sprintf("⛔️N/A-%s", strings.Join(remark, "-"))
|
return fmt.Sprintf("⛔️N/A%s%s", separationChar, strings.Join(remark, separationChar))
|
||||||
}
|
}
|
||||||
if vol := stats.Total - (stats.Up + stats.Down); vol > 0 {
|
if vol := stats.Total - (stats.Up + stats.Down); vol > 0 {
|
||||||
remark = append(remark, fmt.Sprintf("%s%s", common.FormatTraffic(vol), "📊"))
|
remark = append(remark, fmt.Sprintf("%s%s", common.FormatTraffic(vol), "📊"))
|
||||||
|
@ -898,7 +916,7 @@ func (s *SubService) genRemark(inbound *model.Inbound, email string, extra strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(remark, " : ")
|
return strings.Join(remark, separationChar)
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchKey(data interface{}, key string) (interface{}, bool) {
|
func searchKey(data interface{}, key string) (interface{}, bool) {
|
||||||
|
|
|
@ -137,8 +137,8 @@ class DBInbound {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get genInboundLinks() {
|
genInboundLinks() {
|
||||||
const inbound = this.toInbound();
|
const inbound = this.toInbound();
|
||||||
return inbound.genInboundLinks(this.remark);
|
return inbound.genInboundLinks(this.remark,remarkModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ class AllSetting {
|
||||||
this.pageSize = 0;
|
this.pageSize = 0;
|
||||||
this.expireDiff = "";
|
this.expireDiff = "";
|
||||||
this.trafficDiff = "";
|
this.trafficDiff = "";
|
||||||
|
this.remarkModel = "-ieo";
|
||||||
this.tgBotEnable = false;
|
this.tgBotEnable = false;
|
||||||
this.tgBotToken = "";
|
this.tgBotToken = "";
|
||||||
this.tgBotChatId = "";
|
this.tgBotChatId = "";
|
||||||
|
|
|
@ -1566,20 +1566,28 @@ class Inbound extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
genAllLinks(remark='', client){
|
genAllLinks(remark='', remarkModel = '-ieo', client){
|
||||||
let result = [];
|
let result = [];
|
||||||
let email = client ? client.email : '';
|
let email = client ? client.email : '';
|
||||||
let addr = !ObjectUtil.isEmpty(this.listen) && this.listen !== "0.0.0.0" ? this.listen : location.hostname;
|
let addr = !ObjectUtil.isEmpty(this.listen) && this.listen !== "0.0.0.0" ? this.listen : location.hostname;
|
||||||
let port = this.port
|
let port = this.port;
|
||||||
|
const separationChar = remarkModel.charAt(0);
|
||||||
|
const orderChars = remarkModel.slice(1);
|
||||||
|
let orders = {
|
||||||
|
'i': remark,
|
||||||
|
'e': client ? client.email : '',
|
||||||
|
'o': '',
|
||||||
|
};
|
||||||
if(ObjectUtil.isArrEmpty(this.stream.externalProxy)){
|
if(ObjectUtil.isArrEmpty(this.stream.externalProxy)){
|
||||||
let r = [remark, email].filter(x => x.length > 0).join('-');
|
let r = orderChars.split('').map(char => orders[char]).filter(x => x.length > 0).join(separationChar);
|
||||||
result.push({
|
result.push({
|
||||||
remark: r,
|
remark: r,
|
||||||
link: this.genLink(addr, port, 'same', r, client)
|
link: this.genLink(addr, port, 'same', r, client)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.stream.externalProxy.forEach((ep) => {
|
this.stream.externalProxy.forEach((ep) => {
|
||||||
let r = [remark, email, ep.remark].filter(x => x.length > 0).join('-')
|
orders['o'] = ep.remark;
|
||||||
|
let r = orderChars.split('').map(char => orders[char]).filter(x => x.length > 0).join(separationChar);
|
||||||
result.push({
|
result.push({
|
||||||
remark: r,
|
remark: r,
|
||||||
link: this.genLink(ep.dest, ep.port, ep.forceTls, r, client)
|
link: this.genLink(ep.dest, ep.port, ep.forceTls, r, client)
|
||||||
|
@ -1589,11 +1597,11 @@ class Inbound extends XrayCommonClass {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
genInboundLinks(remark = '') {
|
genInboundLinks(remark = '', remarkModel = '-ieo') {
|
||||||
if(this.clients){
|
if(this.clients){
|
||||||
let links = [];
|
let links = [];
|
||||||
this.clients.forEach((client) => {
|
this.clients.forEach((client) => {
|
||||||
genAllLinks(remark,client).forEach(l => {
|
genAllLinks(remark,remarkModel,client).forEach(l => {
|
||||||
links.push(l.link);
|
links.push(l.link);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,6 +25,7 @@ type AllSetting struct {
|
||||||
PageSize int `json:"pageSize" form:"pageSize"`
|
PageSize int `json:"pageSize" form:"pageSize"`
|
||||||
ExpireDiff int `json:"expireDiff" form:"expireDiff"`
|
ExpireDiff int `json:"expireDiff" form:"expireDiff"`
|
||||||
TrafficDiff int `json:"trafficDiff" form:"trafficDiff"`
|
TrafficDiff int `json:"trafficDiff" form:"trafficDiff"`
|
||||||
|
RemarkModel string `json:"remarkModel" form:"remarkModel"`
|
||||||
TgBotEnable bool `json:"tgBotEnable" form:"tgBotEnable"`
|
TgBotEnable bool `json:"tgBotEnable" form:"tgBotEnable"`
|
||||||
TgBotToken string `json:"tgBotToken" form:"tgBotToken"`
|
TgBotToken string `json:"tgBotToken" form:"tgBotToken"`
|
||||||
TgBotChatId string `json:"tgBotChatId" form:"tgBotChatId"`
|
TgBotChatId string `json:"tgBotChatId" form:"tgBotChatId"`
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.subId = '';
|
this.subId = '';
|
||||||
this.qrcodes = [];
|
this.qrcodes = [];
|
||||||
this.inbound.genAllLinks(this.dbInbound.remark, client).forEach(l => {
|
this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, client).forEach(l => {
|
||||||
this.qrcodes.push({
|
this.qrcodes.push({
|
||||||
remark: l.remark,
|
remark: l.remark,
|
||||||
link: l.link
|
link: l.link
|
||||||
|
|
|
@ -264,7 +264,7 @@
|
||||||
this.clientSettings = this.inbound.clients ? this.inbound.clients[index] : null;
|
this.clientSettings = this.inbound.clients ? this.inbound.clients[index] : null;
|
||||||
this.isExpired = this.inbound.clients ? this.inbound.isExpiry(index): this.dbInbound.isExpiry;
|
this.isExpired = this.inbound.clients ? this.inbound.isExpiry(index): this.dbInbound.isExpiry;
|
||||||
this.clientStats = this.inbound.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : [];
|
this.clientStats = this.inbound.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : [];
|
||||||
this.links = this.inbound.genAllLinks(this.dbInbound.remark, this.clientSettings);
|
this.links = this.inbound.genAllLinks(this.dbInbound.remark, app.remarkModel, this.clientSettings);
|
||||||
if (this.clientSettings) {
|
if (this.clientSettings) {
|
||||||
if (this.clientSettings.subId) {
|
if (this.clientSettings.subId) {
|
||||||
this.subLink = this.genSubLink(this.clientSettings.subId);
|
this.subLink = this.genSubLink(this.clientSettings.subId);
|
||||||
|
|
|
@ -556,6 +556,7 @@
|
||||||
enable : false,
|
enable : false,
|
||||||
subURI : ''
|
subURI : ''
|
||||||
},
|
},
|
||||||
|
remarkModel: '-ieo',
|
||||||
tgBotEnable: false,
|
tgBotEnable: false,
|
||||||
pageSize: 0,
|
pageSize: 0,
|
||||||
isMobile: window.innerWidth <= 768,
|
isMobile: window.innerWidth <= 768,
|
||||||
|
@ -600,6 +601,7 @@
|
||||||
subURI: subURI
|
subURI: subURI
|
||||||
};
|
};
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
|
this.remarkModel = remarkModel;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setInbounds(dbInbounds) {
|
setInbounds(dbInbounds) {
|
||||||
|
@ -1191,7 +1193,7 @@
|
||||||
exportAllLinks() {
|
exportAllLinks() {
|
||||||
let copyText = [];
|
let copyText = [];
|
||||||
for (const dbInbound of this.dbInbounds) {
|
for (const dbInbound of this.dbInbounds) {
|
||||||
copyText.push(dbInbound.genInboundLinks);
|
copyText.push(dbInbound.genInboundLinks(this.remarkModel));
|
||||||
}
|
}
|
||||||
txtModal.show('{{ i18n "pages.inbounds.export"}}', copyText.join('\r\n'), 'All-Inbounds');
|
txtModal.show('{{ i18n "pages.inbounds.export"}}', copyText.join('\r\n'), 'All-Inbounds');
|
||||||
},
|
},
|
||||||
|
|
|
@ -105,6 +105,28 @@
|
||||||
<a-tabs default-active-key="1">
|
<a-tabs default-active-key="1">
|
||||||
<a-tab-pane key="1" tab='{{ i18n "pages.settings.panelSettings"}}'>
|
<a-tab-pane key="1" tab='{{ i18n "pages.settings.panelSettings"}}'>
|
||||||
<a-list item-layout="horizontal">
|
<a-list item-layout="horizontal">
|
||||||
|
<a-list-item>
|
||||||
|
<a-row style="padding: 20px">
|
||||||
|
<a-col :lg="24" :xl="12">
|
||||||
|
<a-list-item-meta title='{{ i18n "pages.settings.remarkModel"}}'>
|
||||||
|
<template slot="description">{{ i18n "pages.settings.sampleRemark"}}: <i>#[[ remarkSample ]]</i></template>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="24" :xl="12">
|
||||||
|
<a-input-group style="width: 100%;">
|
||||||
|
<a-select style="padding-right: .5rem; min-width: 80%; width: auto;"
|
||||||
|
mode="multiple"
|
||||||
|
v-model="remarkModel"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option v-for="(value, key) in remarkModels" :value="key">[[ value ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<a-select style="width: 20%;" v-model="remarkSeparator" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option v-for="key in remarkSeparators" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-input-group>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-list-item>
|
||||||
<setting-list-item type="text" title='{{ i18n "pages.settings.panelListeningIP"}}' desc='{{ i18n "pages.settings.panelListeningIPDesc"}}' v-model="allSetting.webListen"></setting-list-item>
|
<setting-list-item type="text" title='{{ i18n "pages.settings.panelListeningIP"}}' desc='{{ i18n "pages.settings.panelListeningIPDesc"}}' v-model="allSetting.webListen"></setting-list-item>
|
||||||
<setting-list-item type="text" title='{{ i18n "pages.settings.panelListeningDomain"}}' desc='{{ i18n "pages.settings.panelListeningDomainDesc"}}' v-model="allSetting.webDomain"></setting-list-item>
|
<setting-list-item type="text" title='{{ i18n "pages.settings.panelListeningDomain"}}' desc='{{ i18n "pages.settings.panelListeningDomainDesc"}}' v-model="allSetting.webDomain"></setting-list-item>
|
||||||
<setting-list-item type="number" title='{{ i18n "pages.settings.panelPort"}}' desc='{{ i18n "pages.settings.panelPortDesc"}}' v-model="allSetting.webPort" :min="0"></setting-list-item>
|
<setting-list-item type="number" title='{{ i18n "pages.settings.panelPort"}}' desc='{{ i18n "pages.settings.panelPortDesc"}}' v-model="allSetting.webPort" :min="0"></setting-list-item>
|
||||||
|
@ -272,6 +294,31 @@
|
||||||
saveBtnDisable: true,
|
saveBtnDisable: true,
|
||||||
user: {},
|
user: {},
|
||||||
lang: getLang(),
|
lang: getLang(),
|
||||||
|
showAlert: false,
|
||||||
|
remarkModels: {i:'Inbound',e:'Email',o:'Other'},
|
||||||
|
remarkSeparators: [' ','-','_','@',':','~','|',',','.','/'],
|
||||||
|
remarkSample: '',
|
||||||
|
get remarkModel() {
|
||||||
|
rm = this.allSetting.remarkModel;
|
||||||
|
return rm.length>1 ? rm.substring(1).split('') : [];
|
||||||
|
},
|
||||||
|
set remarkModel(value) {
|
||||||
|
rs = this.allSetting.remarkModel[0];
|
||||||
|
this.allSetting.remarkModel = rs + value.join('');
|
||||||
|
this.changeRemarkSample();
|
||||||
|
},
|
||||||
|
get remarkSeparator() {
|
||||||
|
return this.allSetting.remarkModel.length > 1 ? this.allSetting.remarkModel.charAt(0) : '-';
|
||||||
|
},
|
||||||
|
set remarkSeparator(value) {
|
||||||
|
this.allSetting.remarkModel = value + this.allSetting.remarkModel.substring(1);
|
||||||
|
this.changeRemarkSample();
|
||||||
|
},
|
||||||
|
changeRemarkSample(){
|
||||||
|
sample = []
|
||||||
|
this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
|
||||||
|
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loading(spinning = true) {
|
loading(spinning = true) {
|
||||||
|
@ -284,6 +331,7 @@
|
||||||
if (msg.success) {
|
if (msg.success) {
|
||||||
this.oldAllSetting = new AllSetting(msg.obj);
|
this.oldAllSetting = new AllSetting(msg.obj);
|
||||||
this.allSetting = new AllSetting(msg.obj);
|
this.allSetting = new AllSetting(msg.obj);
|
||||||
|
app.changeRemarkSample();
|
||||||
this.saveBtnDisable = true;
|
this.saveBtnDisable = true;
|
||||||
}
|
}
|
||||||
await this.fetchUserSecret();
|
await this.fetchUserSecret();
|
||||||
|
|
|
@ -34,6 +34,7 @@ var defaultValueMap = map[string]string{
|
||||||
"pageSize": "0",
|
"pageSize": "0",
|
||||||
"expireDiff": "0",
|
"expireDiff": "0",
|
||||||
"trafficDiff": "0",
|
"trafficDiff": "0",
|
||||||
|
"remarkModel": "-ieo",
|
||||||
"timeLocation": "Asia/Tehran",
|
"timeLocation": "Asia/Tehran",
|
||||||
"tgBotEnable": "false",
|
"tgBotEnable": "false",
|
||||||
"tgBotToken": "",
|
"tgBotToken": "",
|
||||||
|
@ -311,6 +312,10 @@ func (s *SettingService) GetSessionMaxAge() (int, error) {
|
||||||
return s.getInt("sessionMaxAge")
|
return s.getInt("sessionMaxAge")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SettingService) GetRemarkModel() (string, error) {
|
||||||
|
return s.getString("remarkModel")
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SettingService) GetSecretStatus() (bool, error) {
|
func (s *SettingService) GetSecretStatus() (bool, error) {
|
||||||
return s.getBool("secretEnable")
|
return s.getBool("secretEnable")
|
||||||
}
|
}
|
||||||
|
@ -457,6 +462,7 @@ func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) {
|
||||||
"tgBotEnable": func() (interface{}, error) { return s.GetTgbotenabled() },
|
"tgBotEnable": func() (interface{}, error) { return s.GetTgbotenabled() },
|
||||||
"subEnable": func() (interface{}, error) { return s.GetSubEnable() },
|
"subEnable": func() (interface{}, error) { return s.GetSubEnable() },
|
||||||
"subURI": func() (interface{}, error) { return s.GetSubURI() },
|
"subURI": func() (interface{}, error) { return s.GetSubURI() },
|
||||||
|
"remarkModel": func() (interface{}, error) { return s.GetRemarkModel() },
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make(map[string]interface{})
|
result := make(map[string]interface{})
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"panelUrlPathDesc" = "Must start with '/' and end with."
|
"panelUrlPathDesc" = "Must start with '/' and end with."
|
||||||
"pageSize" = "Pagination size"
|
"pageSize" = "Pagination size"
|
||||||
"pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable"
|
"pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable"
|
||||||
|
"remarkModel" = "Remark Model and Seperation charachter"
|
||||||
|
"sampleRemark" = "Sample remark"
|
||||||
"oldUsername" = "Current Username"
|
"oldUsername" = "Current Username"
|
||||||
"currentPassword" = "Current Password"
|
"currentPassword" = "Current Password"
|
||||||
"newUsername" = "New Username"
|
"newUsername" = "New Username"
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"panelUrlPathDesc" = "Debe empezar con '/' y terminar con."
|
"panelUrlPathDesc" = "Debe empezar con '/' y terminar con."
|
||||||
"pageSize" = "Tamaño de paginación"
|
"pageSize" = "Tamaño de paginación"
|
||||||
"pageSizeDesc" = "Defina el tamaño de página para la tabla de entradas. Establezca 0 para desactivar"
|
"pageSizeDesc" = "Defina el tamaño de página para la tabla de entradas. Establezca 0 para desactivar"
|
||||||
|
"remarkModel" = "Modelo de observación y carácter de separación"
|
||||||
|
"sampleRemark" = "Observación de muestra"
|
||||||
"oldUsername" = "Nombre de Usuario Actual"
|
"oldUsername" = "Nombre de Usuario Actual"
|
||||||
"currentPassword" = "Contraseña Actual"
|
"currentPassword" = "Contraseña Actual"
|
||||||
"newUsername" = "Nuevo Nombre de Usuario"
|
"newUsername" = "Nuevo Nombre de Usuario"
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"panelUrlPathDesc" = "باید با '/' شروع شود و با '/' تمام شود"
|
"panelUrlPathDesc" = "باید با '/' شروع شود و با '/' تمام شود"
|
||||||
"pageSize" = "اندازه صفحه بندی جدول"
|
"pageSize" = "اندازه صفحه بندی جدول"
|
||||||
"pageSizeDesc" = "اندازه صفحه را برای جدول سرویس ها تعریف کنید. 0: غیرفعال"
|
"pageSizeDesc" = "اندازه صفحه را برای جدول سرویس ها تعریف کنید. 0: غیرفعال"
|
||||||
|
"remarkModel" = "نام کانفیگ و جداکننده"
|
||||||
|
"sampleRemark" = "نمونه نام"
|
||||||
"oldUsername" = "نام کاربری فعلی"
|
"oldUsername" = "نام کاربری فعلی"
|
||||||
"currentPassword" = "رمز عبور فعلی"
|
"currentPassword" = "رمز عبور فعلی"
|
||||||
"newUsername" = "نام کاربری جدید"
|
"newUsername" = "نام کاربری جدید"
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"panelUrlPathDesc" = "Должен начинаться с '/' и заканчиваться на"
|
"panelUrlPathDesc" = "Должен начинаться с '/' и заканчиваться на"
|
||||||
"pageSize" = "Размер нумерации страниц"
|
"pageSize" = "Размер нумерации страниц"
|
||||||
"pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить"
|
"pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить"
|
||||||
|
"remarkModel" = "Модель примечания и символ разделения"
|
||||||
|
"sampleRemark" = "Пример замечания"
|
||||||
"oldUsername" = "Текущее имя пользователя"
|
"oldUsername" = "Текущее имя пользователя"
|
||||||
"currentPassword" = "Текущий пароль"
|
"currentPassword" = "Текущий пароль"
|
||||||
"newUsername" = "Новое имя пользователя"
|
"newUsername" = "Новое имя пользователя"
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"panelUrlPathDesc" = "Phải bắt đầu bằng '/' và kết thúc bằng."
|
"panelUrlPathDesc" = "Phải bắt đầu bằng '/' và kết thúc bằng."
|
||||||
"pageSize" = "Kích thước phân trang"
|
"pageSize" = "Kích thước phân trang"
|
||||||
"pageSizeDesc" = "Xác định kích thước trang cho bảng gửi đến. Đặt 0 để tắt"
|
"pageSizeDesc" = "Xác định kích thước trang cho bảng gửi đến. Đặt 0 để tắt"
|
||||||
|
"remarkModel" = "Ghi chú mô hình và ký tự phân tách"
|
||||||
|
"sampleRemark" = "Nhận xét mẫu"
|
||||||
"oldUsername" = "Tên người dùng hiện tại"
|
"oldUsername" = "Tên người dùng hiện tại"
|
||||||
"currentPassword" = "Mật khẩu hiện tại"
|
"currentPassword" = "Mật khẩu hiện tại"
|
||||||
"newUsername" = "Tên người dùng mới"
|
"newUsername" = "Tên người dùng mới"
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"panelUrlPathDesc" = "必须以 '/' 开头,以 '/' 结尾"
|
"panelUrlPathDesc" = "必须以 '/' 开头,以 '/' 结尾"
|
||||||
"pageSize" = "分页大小"
|
"pageSize" = "分页大小"
|
||||||
"pageSizeDesc" = "定义入站表的页面大小。设置 0 表示禁用"
|
"pageSizeDesc" = "定义入站表的页面大小。设置 0 表示禁用"
|
||||||
|
"remarkModel" = "备注模型和分隔符"
|
||||||
|
"sampleRemark" = "备注示例"
|
||||||
"oldUsername" = "原用户名"
|
"oldUsername" = "原用户名"
|
||||||
"currentPassword" = "原密码"
|
"currentPassword" = "原密码"
|
||||||
"newUsername" = "新用户名"
|
"newUsername" = "新用户名"
|
||||||
|
|
Loading…
Reference in a new issue