diff --git a/database/model/model.go b/database/model/model.go
index 86ab0487..62cfac41 100644
--- a/database/model/model.go
+++ b/database/model/model.go
@@ -32,6 +32,7 @@ type Inbound struct {
Up int64 `json:"up" form:"up"`
Down int64 `json:"down" form:"down"`
Total int64 `json:"total" form:"total"`
+ AllTime int64 `json:"allTime" form:"allTime" gorm:"default:0"`
Remark string `json:"remark" form:"remark"`
Enable bool `json:"enable" form:"enable"`
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
diff --git a/web/assets/js/model/dbinbound.js b/web/assets/js/model/dbinbound.js
index 45301ddd..acb62ce4 100644
--- a/web/assets/js/model/dbinbound.js
+++ b/web/assets/js/model/dbinbound.js
@@ -6,6 +6,7 @@ class DBInbound {
this.up = 0;
this.down = 0;
this.total = 0;
+ this.allTime = 0;
this.remark = "";
this.enable = true;
this.expiryTime = 0;
diff --git a/web/html/component/aClientTable.html b/web/html/component/aClientTable.html
index 359e6e74..53ec27a3 100644
--- a/web/html/component/aClientTable.html
+++ b/web/html/component/aClientTable.html
@@ -98,6 +98,10 @@
+
+
+ [[ SizeFormatter.sizeFormat(getAllTimeClient(record, client.email)) ]]
+
diff --git a/web/html/inbounds.html b/web/html/inbounds.html
index 010296eb..142a167c 100644
--- a/web/html/inbounds.html
+++ b/web/html/inbounds.html
@@ -167,28 +167,35 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
-
+
@@ -484,6 +491,9 @@
+
+ [[ SizeFormatter.sizeFormat(dbInbound.allTime || 0) ]]
+
@@ -723,6 +733,11 @@
align: 'center',
width: 60,
scopedSlots: { customRender: 'traffic' },
+ }, {
+ title: '{{ i18n "pages.inbounds.allTimeTraffic" }}',
+ align: 'center',
+ width: 60,
+ scopedSlots: { customRender: 'allTimeInbound' },
}, {
title: '{{ i18n "pages.inbounds.expireDate" }}',
align: 'center',
@@ -759,6 +774,7 @@
{ title: '{{ i18n "online" }}', width: 30, scopedSlots: { customRender: 'online' } },
{ title: '{{ i18n "pages.inbounds.client" }}', width: 80, scopedSlots: { customRender: 'client' } },
{ title: '{{ i18n "pages.inbounds.traffic" }}', width: 80, align: 'center', scopedSlots: { customRender: 'traffic' } },
+ { title: '{{ i18n "pages.inbounds.allTimeTraffic" }}', width: 80, align: 'center', scopedSlots: { customRender: 'allTime' } },
{ title: '{{ i18n "pages.inbounds.expireDate" }}', width: 80, align: 'center', scopedSlots: { customRender: 'expiryTime' } },
{ title: '{{ i18n "pages.inbounds.createdAt" }}', width: 90, align: 'center', scopedSlots: { customRender: 'createdAt' } },
{ title: '{{ i18n "pages.inbounds.updatedAt" }}', width: 90, align: 'center', scopedSlots: { customRender: 'updatedAt' } },
@@ -1419,6 +1435,12 @@
clientStats = dbInbound.clientStats.find(stats => stats.email === email);
return clientStats ? clientStats.up + clientStats.down : 0;
},
+ getAllTimeClient(dbInbound, email) {
+ if (email.length == 0) return 0;
+ clientStats = dbInbound.clientStats.find(stats => stats.email === email);
+ if (!clientStats) return 0;
+ return clientStats.allTime || (clientStats.up + clientStats.down);
+ },
getRemStats(dbInbound, email) {
if (email.length == 0) return 0;
clientStats = dbInbound.clientStats.find(stats => stats.email === email);
@@ -1608,11 +1630,12 @@
},
computed: {
total() {
- let down = 0, up = 0;
+ let down = 0, up = 0, allTime = 0;
let clients = 0, deactive = [], depleted = [], expiring = [];
this.dbInbounds.forEach(dbInbound => {
down += dbInbound.down;
up += dbInbound.up;
+ allTime += (dbInbound.allTime || (dbInbound.up + dbInbound.down));
if (this.clientCount[dbInbound.id]) {
clients += this.clientCount[dbInbound.id].clients;
deactive = deactive.concat(this.clientCount[dbInbound.id].deactive);
@@ -1623,6 +1646,7 @@
return {
down: down,
up: up,
+ allTime: allTime,
clients: clients,
deactive: deactive,
depleted: depleted,
diff --git a/web/service/inbound.go b/web/service/inbound.go
index 4ef5fce3..78abef73 100644
--- a/web/service/inbound.go
+++ b/web/service/inbound.go
@@ -915,8 +915,9 @@ func (s *InboundService) addInboundTraffic(tx *gorm.DB, traffics []*xray.Traffic
if traffic.IsInbound {
err = tx.Model(&model.Inbound{}).Where("tag = ?", traffic.Tag).
Updates(map[string]any{
- "up": gorm.Expr("up + ?", traffic.Up),
- "down": gorm.Expr("down + ?", traffic.Down),
+ "up": gorm.Expr("up + ?", traffic.Up),
+ "down": gorm.Expr("down + ?", traffic.Down),
+ "all_time": gorm.Expr("COALESCE(all_time, 0) + ?", traffic.Up+traffic.Down),
}).Error
if err != nil {
return err
@@ -962,6 +963,7 @@ func (s *InboundService) addClientTraffic(tx *gorm.DB, traffics []*xray.ClientTr
if dbClientTraffics[dbTraffic_index].Email == traffics[traffic_index].Email {
dbClientTraffics[dbTraffic_index].Up += traffics[traffic_index].Up
dbClientTraffics[dbTraffic_index].Down += traffics[traffic_index].Down
+ dbClientTraffics[dbTraffic_index].AllTime += (traffics[traffic_index].Up + traffics[traffic_index].Down)
// Add user in onlineUsers array on traffic
if traffics[traffic_index].Up+traffics[traffic_index].Down > 0 {
@@ -2035,6 +2037,26 @@ func (s *InboundService) MigrationRequirements() {
tx.Rollback()
}
}()
+
+
+ // Calculate and backfill all_time from up+down for inbounds and clients
+ err = tx.Exec(`
+ UPDATE inbounds
+ SET all_time = IFNULL(up, 0) + IFNULL(down, 0)
+ WHERE IFNULL(all_time, 0) = 0 AND (IFNULL(up, 0) + IFNULL(down, 0)) > 0
+ `).Error
+ if err != nil {
+ return
+ }
+ err = tx.Exec(`
+ UPDATE client_traffics
+ SET all_time = IFNULL(up, 0) + IFNULL(down, 0)
+ WHERE IFNULL(all_time, 0) = 0 AND (IFNULL(up, 0) + IFNULL(down, 0)) > 0
+ `).Error
+
+ if err != nil {
+ return
+ }
// Fix inbounds based problems
var inbounds []*model.Inbound
diff --git a/web/translation/translate.ar_EG.toml b/web/translation/translate.ar_EG.toml
index 4e4aac75..bbf68822 100644
--- a/web/translation/translate.ar_EG.toml
+++ b/web/translation/translate.ar_EG.toml
@@ -151,6 +151,8 @@
"getConfigError" = "حدث خطأ أثناء استرجاع ملف الإعدادات"
[pages.inbounds]
+"allTimeTraffic" = "إجمالي حركة المرور"
+"allTimeTrafficUsage" = "إجمالي الاستخدام طوال الوقت"
"title" = "الإدخالات"
"totalDownUp" = "إجمالي المرسل/المستقبل"
"totalUsage" = "إجمالي الاستخدام"
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index 4e27908d..1531fe30 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -151,6 +151,8 @@
"getConfigError" = "An error occurred while retrieving the config file."
[pages.inbounds]
+"allTimeTraffic" = "All-time Traffic"
+"allTimeTrafficUsage" = "All Time Total Usage"
"title" = "Inbounds"
"totalDownUp" = "Total Sent/Received"
"totalUsage" = "Total Usage"
diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml
index 3ad93de2..6a2b8958 100644
--- a/web/translation/translate.es_ES.toml
+++ b/web/translation/translate.es_ES.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Ocurrió un error al obtener el archivo de configuración"
[pages.inbounds]
+"allTimeTraffic" = "Tráfico Total"
+"allTimeTrafficUsage" = "Uso total de todos los tiempos"
"title" = "Entradas"
"totalDownUp" = "Subidas/Descargas Totales"
"totalUsage" = "Uso Total"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index 5e810e62..fb6d9f02 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -151,6 +151,8 @@
"getConfigError" = "خطا در دریافت فایل پیکربندی"
[pages.inbounds]
+"allTimeTraffic" = "کل ترافیک"
+"allTimeTrafficUsage" = "کل استفاده در تمام مدت"
"title" = "کاربران"
"totalDownUp" = "دریافت/ارسال کل"
"totalUsage" = "مصرف کل"
diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml
index dcfe68c0..d0d77dc3 100644
--- a/web/translation/translate.id_ID.toml
+++ b/web/translation/translate.id_ID.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Terjadi kesalahan saat mengambil file konfigurasi"
[pages.inbounds]
+"allTimeTraffic" = "Total Lalu Lintas"
+"allTimeTrafficUsage" = "Total Penggunaan Sepanjang Waktu"
"title" = "Masuk"
"totalDownUp" = "Total Terkirim/Diterima"
"totalUsage" = "Penggunaan Total"
diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml
index a8702cd8..3f89cf0c 100644
--- a/web/translation/translate.ja_JP.toml
+++ b/web/translation/translate.ja_JP.toml
@@ -151,6 +151,8 @@
"getConfigError" = "設定ファイルの取得中にエラーが発生しました"
[pages.inbounds]
+"allTimeTraffic" = "総トラフィック"
+"allTimeTrafficUsage" = "これまでの総使用量"
"title" = "インバウンド一覧"
"totalDownUp" = "総アップロード / ダウンロード"
"totalUsage" = "総使用量"
diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml
index 813a4dde..3755c61e 100644
--- a/web/translation/translate.pt_BR.toml
+++ b/web/translation/translate.pt_BR.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Ocorreu um erro ao recuperar o arquivo de configuração"
[pages.inbounds]
+"allTimeTraffic" = "Tráfego Total"
+"allTimeTrafficUsage" = "Uso total de todos os tempos"
"title" = "Inbounds"
"totalDownUp" = "Total Enviado/Recebido"
"totalUsage" = "Uso Total"
diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml
index be4a1ef3..8efc4673 100644
--- a/web/translation/translate.ru_RU.toml
+++ b/web/translation/translate.ru_RU.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Произошла ошибка при получении конфигурационного файла"
[pages.inbounds]
+"allTimeTraffic" = "Общий трафик"
+"allTimeTrafficUsage" = "Общее использование за все время"
"title" = "Инбаунды"
"totalDownUp" = "Объем отправленного/полученного трафика"
"totalUsage" = "Всего трафика"
diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml
index 7159c9b5..a298dd30 100644
--- a/web/translation/translate.tr_TR.toml
+++ b/web/translation/translate.tr_TR.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Yapılandırma dosyası alınırken bir hata oluştu"
[pages.inbounds]
+"allTimeTraffic" = "Toplam Trafik"
+"allTimeTrafficUsage" = "Tüm Zamanların Toplam Kullanımı"
"title" = "Gelenler"
"totalDownUp" = "Toplam Gönderilen/Alınan"
"totalUsage" = "Toplam Kullanım"
diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml
index 95eca7a6..02ed7352 100644
--- a/web/translation/translate.uk_UA.toml
+++ b/web/translation/translate.uk_UA.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Виникла помилка під час отримання файлу конфігурації"
[pages.inbounds]
+"allTimeTraffic" = "Загальний трафік"
+"allTimeTrafficUsage" = "Загальне використання за весь час"
"title" = "Вхідні"
"totalDownUp" = "Всього надісланих/отриманих"
"totalUsage" = "Всього використанно"
diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml
index f8144a2f..3f61874f 100644
--- a/web/translation/translate.vi_VN.toml
+++ b/web/translation/translate.vi_VN.toml
@@ -151,6 +151,8 @@
"getConfigError" = "Lỗi xảy ra khi truy xuất tệp cấu hình"
[pages.inbounds]
+"allTimeTraffic" = "Tổng Lưu Lượng"
+"allTimeTrafficUsage" = "Tổng mức sử dụng mọi lúc"
"title" = "Điểm vào (Inbounds)"
"totalDownUp" = "Tổng tải lên/tải xuống"
"totalUsage" = "Tổng sử dụng"
diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml
index 6490372c..bf19cfdb 100644
--- a/web/translation/translate.zh_CN.toml
+++ b/web/translation/translate.zh_CN.toml
@@ -151,6 +151,8 @@
"getConfigError" = "检索配置文件时出错"
[pages.inbounds]
+"allTimeTraffic" = "累计总流量"
+"allTimeTrafficUsage" = "所有时间总使用量"
"title" = "入站列表"
"totalDownUp" = "总上传 / 下载"
"totalUsage" = "总用量"
diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml
index cd4f22e7..dfd284d2 100644
--- a/web/translation/translate.zh_TW.toml
+++ b/web/translation/translate.zh_TW.toml
@@ -151,6 +151,8 @@
"getConfigError" = "檢索設定檔時發生錯誤"
[pages.inbounds]
+"allTimeTraffic" = "累計總流量"
+"allTimeTrafficUsage" = "所有时间总使用量"
"title" = "入站列表"
"totalDownUp" = "總上傳 / 下載"
"totalUsage" = "總用量"
diff --git a/xray/client_traffic.go b/xray/client_traffic.go
index 0f2389a0..883de2cc 100644
--- a/xray/client_traffic.go
+++ b/xray/client_traffic.go
@@ -7,6 +7,7 @@ type ClientTraffic struct {
Email string `json:"email" form:"email" gorm:"unique"`
Up int64 `json:"up" form:"up"`
Down int64 `json:"down" form:"down"`
+ AllTime int64 `json:"allTime" form:"allTime"`
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
Total int64 `json:"total" form:"total"`
Reset int `json:"reset" form:"reset" gorm:"default:0"`