Add Inbound
Export Links
@@ -67,6 +77,12 @@
{{ i18n "edit" }}
+
+
+
+ {{ i18n "pages.inbounds.export"}}
+
+
{{ i18n "pages.inbounds.resetTraffic" }}
@@ -202,7 +218,7 @@
{ title: '{{ i18n "pages.inbounds.client" }}', width: 60, scopedSlots: { customRender: 'client' } },
{ title: '{{ i18n "pages.inbounds.traffic" }}↑|↓', width: 100, scopedSlots: { customRender: 'traffic' } },
{ title: '{{ i18n "pages.inbounds.expireDate" }}', width: 70, scopedSlots: { customRender: 'expiryTime' } },
- { title: 'UID', width: 120, dataIndex: "id" },
+ { title: 'UID', width: 150, dataIndex: "id" },
];
@@ -281,6 +297,9 @@
case "qrcode":
this.showQrcode(dbInbound);
break;
+ case "export":
+ this.inboundLinks(dbInbound.id);
+ break;
case "edit":
this.openEditInbound(dbInbound.id);
break;
@@ -372,18 +391,6 @@
},
});
},
- exportAllLinks() {
- let copyText = '';
- for (const dbInbound of this.dbInbounds) {
- copyText += dbInbound.genInboundLinks
- }
- const clipboard = new ClipboardJS('.copy-btn', {
- text: function () {
- return copyText;
- }
- });
- clipboard.on('success', () => { this.$message.success('Export Links succeed'); });
- },
delInbound(dbInbound) {
this.$confirm({
title: '{{ i18n "pages.inbounds.deleteInbound"}}',
@@ -393,7 +400,15 @@
onOk: () => this.submit('/xui/inbound/del/' + dbInbound.id),
});
},
- showQrcode(dbInbound, clientIndex) {
+ getClients(protocol, clientSettings) {
+ switch(protocol){
+ case Protocols.VMESS: return clientSettings.vmesses;
+ case Protocols.VLESS: return clientSettings.vlesses;
+ case Protocols.TROJAN: return clientSettings.trojans;
+ default: return null;
+ }
+ },
+ showQrcode(dbInbound, clientIndex) {
const link = dbInbound.genLink(clientIndex);
qrModal.show('{{ i18n "qrCode"}}', link, dbInbound);
},
@@ -451,60 +466,34 @@
return dbInbound.toInbound().isExpiry(index)
},
getUpStats(dbInbound, email) {
- clientStats = dbInbound.clientStats
- if(clientStats.length > 0)
- {
- for (const key in clientStats) {
- if (Object.hasOwnProperty.call(clientStats, key)) {
- if(clientStats[key]['email'] == email)
- return clientStats[key]['up']
-
- }
- }
- }
-
+ if(email.length == 0) return 0
+ clientStats = dbInbound.clientStats.find(stats => stats.email === email)
+ return clientStats ? clientStats.up : 0
},
getDownStats(dbInbound, email) {
- clientStats = dbInbound.clientStats
- if(clientStats.length > 0)
- {
- for (const key in clientStats) {
- if (Object.hasOwnProperty.call(clientStats, key)) {
- if(clientStats[key]['email'] == email)
- return clientStats[key]['down']
-
- }
- }
- }
+ if(email.length == 0) return 0
+ clientStats = dbInbound.clientStats.find(stats => stats.email === email)
+ return clientStats ? clientStats.down : 0
},
isTrafficExhausted(dbInbound, email) {
- clientStats = dbInbound.clientStats
- if(clientStats.length > 0)
- {
- for (const key in clientStats) {
- if (Object.hasOwnProperty.call(clientStats, key)) {
- if(clientStats[key]['email'] == email)
- return clientStats[key]['down']+clientStats[key]['up'] > clientStats[key]['total']
-
- }
- }
+ if(email.length == 0) return false
+ clientStats = dbInbound.clientStats.find(stats => stats.email === email)
+ return clientStats ? clientStats.down + clientStats.up > clientStats.total : false
+ },
+ inboundLinks(dbInboundId) {
+ dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
+ txtModal.show('{{ i18n "pages.inbounds.export"}}',dbInbound.genInboundLinks,dbInbound.remark);
+ },
+ exportAllLinks() {
+ let copyText = '';
+ for (const dbInbound of this.dbInbounds) {
+ copyText += dbInbound.genInboundLinks
}
+ txtModal.show('{{ i18n "pages.inbounds.export"}}',copyText,'All-Inbounds');
},
isClientEnabled(dbInbound, email) {
- clientStats = dbInbound.clientStats
- if(clientStats.length > 0)
- {
- for (const key in clientStats) {
- if (Object.hasOwnProperty.call(clientStats, key)) {
- if(clientStats[key]['email'] == email)
- return clientStats[key]['enable']
-
- }
- }
- }
- else{
- return true
- }
+ clientStats = dbInbound.clientStats ? dbInbound.clientStats.find(stats => stats.email === email) : null
+ return clientStats ? clientStats['enable'] : true
},
},
watch: {
@@ -518,13 +507,32 @@
computed: {
total() {
let down = 0, up = 0;
- for (let i = 0; i < this.dbInbounds.length; ++i) {
- down += this.dbInbounds[i].down;
- up += this.dbInbounds[i].up;
- }
+ let clients = 0, active = 0, deactive = 0;
+ this.dbInbounds.forEach(dbInbound => {
+ down += dbInbound.down;
+ up += dbInbound.up;
+ inbound = dbInbound.toInbound();
+ clients = this.getClients(dbInbound.protocol, inbound.settings);
+ if(clients){
+ if(dbInbound.enable){
+ isClientEnable = false;
+ clients.forEach(client => {
+ isClientEnable = client.email == "" ? true: this.isClientEnabled(dbInbound,client.email);
+ isClientEnable ? active++ : deactive++;
+ });
+ } else {
+ deactive += clients.length;
+ }
+ } else {
+ dbInbound.enable ? active++ : deactive++;
+ }
+ });
return {
down: down,
up: up,
+ clients: active + deactive,
+ active: active,
+ deactive: deactive,
};
}
},
diff --git a/web/html/xui/index.html b/web/html/xui/index.html
index 141174dc..604c6621 100644
--- a/web/html/xui/index.html
+++ b/web/html/xui/index.html
@@ -15,24 +15,26 @@
{{ template "commonSider" . }}
-
+
-
+
CPU
{{ i18n "pages.index.memory"}}: [[ sizeFormat(status.mem.current) ]] / [[ sizeFormat(status.mem.total) ]]
@@ -45,6 +47,7 @@
Swap: [[ sizeFormat(status.swap.current) ]] / [[ sizeFormat(status.swap.total) ]]
@@ -53,6 +56,7 @@
{{ i18n "pages.index.hard"}}: [[ sizeFormat(status.disk.current) ]] / [[ sizeFormat(status.disk.total) ]]
@@ -67,7 +71,7 @@
-
+
{{ i18n "pages.index.xrayStatus" }}:
[[ status.xray.state ]]
@@ -77,11 +81,13 @@
[[ status.xray.version ]]
- {{ i18n "pages.index.xraySwitch"}}
+ {{ i18n "pages.index.stopXray" }}
+ {{ i18n "pages.index.restartXray" }}
+ {{ i18n "pages.index.xraySwitch" }}
-
+
{{ i18n "pages.index.operationHours" }}:
[[ formatSecond(status.uptime) ]]
@@ -93,12 +99,12 @@
-
+
{{ i18n "pages.index.systemLoad" }}: [[ status.loads[0] ]] | [[ status.loads[1] ]] | [[ status.loads[2] ]]
-
+
TCP / UDP {{ i18n "pages.index.connectionCount" }}: [[ status.tcpCount ]] / [[ status.udpCount ]]
@@ -109,7 +115,7 @@
-
+
@@ -135,7 +141,7 @@
-
+
@@ -315,6 +321,24 @@
this.loading(false);
},
});
+ },
+ //here add stop xray function
+ async stopXrayService() {
+ this.loading(true);
+ const msg = await HttpUtil.post('server/stopXrayService');
+ this.loading(false);
+ if (!msg.success) {
+ return;
+ }
+ },
+ //here add restart xray function
+ async restartXrayService() {
+ this.loading(true);
+ const msg = await HttpUtil.post('server/restartXrayService');
+ this.loading(false);
+ if (!msg.success) {
+ return;
+ }
},
},
async mounted() {
diff --git a/web/html/xui/setting.html b/web/html/xui/setting.html
index 67ceaff9..cbbdce1f 100644
--- a/web/html/xui/setting.html
+++ b/web/html/xui/setting.html
@@ -20,14 +20,14 @@
display: block;
}
- .ant-tabs-top-bar {
+ :not(.ant-card-dark)>.ant-tabs-top-bar {
background: white;
}
{{ template "commonSider" . }}
-
+
@@ -35,17 +35,17 @@
{{ i18n "pages.setting.save" }}
{{ i18n "pages.setting.restartPanel" }}
-
+
-
+
-
+
@@ -58,7 +58,7 @@
@change="setLang(lang)"
style="width: 100%"
>
-
+
@@ -71,7 +71,7 @@
-
+
@@ -93,12 +93,12 @@
-
+
-
+
@@ -106,7 +106,7 @@
-
+
diff --git a/web/service/inbound.go b/web/service/inbound.go
index 450c77f0..b3f3265b 100644
--- a/web/service/inbound.go
+++ b/web/service/inbound.go
@@ -275,15 +275,18 @@ func (s *InboundService) AddClientTraffic(traffics []*xray.ClientTraffic) (err e
for _, traffic := range traffics {
inbound := &model.Inbound{}
-
- err := txInbound.Where("settings like ?", "%"+traffic.Email+"%").First(inbound).Error
- traffic.InboundId = inbound.Id
+ client := &xray.ClientTraffic{}
+ err := tx.Where("email = ?", traffic.Email).First(client).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
- // delete removed client record
- clientErr := s.DelClientStat(tx, traffic.Email)
- logger.Warning(err, traffic.Email, clientErr)
-
+ logger.Warning(err, traffic.Email)
+ }
+ continue
+ }
+ err = txInbound.Where("id=?", client.InboundId).First(inbound).Error
+ if err != nil {
+ if err == gorm.ErrRecordNotFound {
+ logger.Warning(err, traffic.Email)
}
continue
}
diff --git a/web/service/server.go b/web/service/server.go
index d12c8e27..31716b9f 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -198,6 +198,30 @@ func (s *ServerService) GetXrayVersions() ([]string, error) {
return versions, nil
}
+func (s *ServerService) StopXrayService() (string error) {
+
+ err := s.xrayService.StopXray()
+ if err != nil {
+ logger.Error("stop xray failed:", err)
+ return err
+ }
+
+ return nil
+}
+
+func (s *ServerService) RestartXrayService() (string error) {
+
+ s.xrayService.StopXray()
+ defer func() {
+ err := s.xrayService.RestartXray(true)
+ if err != nil {
+ logger.Error("start xray failed:", err)
+ }
+ }()
+
+ return nil
+}
+
func (s *ServerService) downloadXRay(version string) (string, error) {
osName := runtime.GOOS
arch := runtime.GOARCH
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index 16424660..0cd7f8ac 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -71,6 +71,8 @@
"hard" = "Hard Disk"
"xrayStatus" = "Xray Status"
"xraySwitch" = "Switch Version"
+"restartXray" = "Restart"
+"stopXray" = "Stop"
"xraySwitchClick" = "Click on the version you want to switch"
"xraySwitchClickDesk" = "Please choose carefully, older versions may have incompatible configurations"
"operationHours" = "Operation Hours"
@@ -87,6 +89,7 @@
"dontRefreshh" = "Installation is in progress, please do not refresh this page"
[pages.inbounds]
+"export" = "Export"
"title" = "Inbounds"
"totalDownUp" = "Total Uploads/Downloads"
"totalUsage" = "Total Usage"
@@ -121,10 +124,10 @@
"noRecommendKeepDefault" = "There are no special requirements to keep the default"
"certificatePath" = "Certificate File Path"
"certificateContent" = "Certificate File Content"
-"publicKeyPath" = "Public Key File Path"
+"publicKeyPath" = "Public Key Path"
"publicKeyContent" = "public Key Content"
-"keyPath" = "Key File Path"
-"keyContent" = "Key Content"
+"keyPath" = "Private key Path"
+"keyContent" = "Private Key Content"
"client" = "Client"
"uid" = "UID"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index 5751588b..d8d7a487 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -71,6 +71,8 @@
"hard" = "حافظه دیسک"
"xrayStatus" = "وضعیت Xray"
"xraySwitch" = "تغییر ورژن"
+"restartXray" = "راه اندازی مجدد"
+"stopXray" = "توقف"
"xraySwitchClick" = "ورژن مورد نظر را انتخاب کنید"
"xraySwitchClickDesk" = "لطفا با دقت انتخاب کنید ، در صورت انتخاب اشتباه امکان قطعی سیستم وجود دارد ."
"operationHours" = "ساعت فعال"
@@ -88,6 +90,7 @@
[pages.inbounds]
+"export" = "استخراج لینکها"
"title" = "کاربران"
"totalDownUp" = "جمع آپلود/دانلود"
"totalUsage" = "جمع کل"
diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml
index 394a4fb5..fa233d20 100644
--- a/web/translation/translate.zh_Hans.toml
+++ b/web/translation/translate.zh_Hans.toml
@@ -70,6 +70,8 @@
"hard" = "硬盘"
"xrayStatus" = "xray 状态"
"xraySwitch" = "切换版本"
+"restartXray" = "重新开始"
+"stopXray" = "停止"
"xraySwitchClick" = "点击你想切换的版本"
"xraySwitchClickDesk" = "请谨慎选择,旧版本可能配置不兼容"
"operationHours" = "运行时间"
@@ -87,6 +89,7 @@
[pages.inbounds]
+"export" = "导出链接"
"title" = "入站列表"
"totalDownUp" = "总上传 / 下载"
"totalUsage" = "总用量"