diff --git a/assets/lang/en.json b/assets/lang/en.json index f28b313..841879a 100644 --- a/assets/lang/en.json +++ b/assets/lang/en.json @@ -48,5 +48,29 @@ "None": "None", "Server Info": "Server Info", "Users": "Users", - "Proxies": "Proxies" + "Proxies": "Proxies", + "Name": "Name", + "Port": "Port", + "Connections": "Connections", + "Traffic In": "Traffic In", + "Traffic Out": "Traffic Out", + "Client Version": "Client Version", + "Traffic Statistics": "Traffic Statistics", + "Type": "Type", + "Domains": "Domains", + "SubDomain": "SubDomain", + "Locations": "Locations", + "HostRewrite": "HostRewrite", + "Encryption": "Encryption", + "Compression": "Compression", + "Addr": "Addr", + "online": "online", + "offline": "offline", + "true": "Yes", + "false": "No", + "Last Start": "Last Start", + "Last Close": "Last Close", + "Network Traffic": "Network Traffic", + "today": "today", + "now": "now" } \ No newline at end of file diff --git a/assets/lang/zh.json b/assets/lang/zh.json index b34b0c3..218e299 100644 --- a/assets/lang/zh.json +++ b/assets/lang/zh.json @@ -20,9 +20,9 @@ "Operation": "操作", "Confirm": "确定", "Cancel": "取消", - "Confirm to remove user": "确定删除用户 ?", - "Confirm to disable user": "确定禁用用户 ?", - "Confirm to enable user": "确定启用用户 ?", + "Confirm to remove user": "确定删除用户?", + "Confirm to disable user": "确定禁用用户?", + "Confirm to enable user": "确定启用用户?", "Operate success": "操作成功", "Operate failed": "操作失败", "Operate error": "操作异常", @@ -48,5 +48,29 @@ "None": "无", "Server Info": "服务器信息", "Users": "用户列表", - "Proxies": "代理列表" + "Proxies": "代理列表", + "Name": "名称", + "Port": "端口", + "Connections": "连接数", + "Traffic In": "入站流量", + "Traffic Out": "出站流量", + "Client Version": "客户端版本", + "Traffic Statistics": "流量统计", + "Type": "连接类型", + "Domains": "自定义域名", + "SubDomain": "二级域名", + "Locations": "路由", + "HostRewrite": "自定义请求头", + "Encryption": "数据加密", + "Compression": "数据压缩", + "Addr": "使用端口", + "online": "在线", + "offline": "离线", + "true": "是", + "false": "否", + "Last Start": "上次连接时间", + "Last Close": "上次断开时间", + "Network Traffic": "网络流量", + "today": "今日", + "now": "当前" } \ No newline at end of file diff --git a/assets/static/css/index-color.css b/assets/static/css/index-color.css index ef37b26..eaebdcf 100644 --- a/assets/static/css/index-color.css +++ b/assets/static/css/index-color.css @@ -79,6 +79,35 @@ color: #99a9bf; } +section.server-info .text-row .text-col:first-child { + color: #99a9bf; +} + +section.proxy-list .proxy-info .layui-row .layui-row > div:first-child { + color: #99a9bf; +} + +.online, +.offline { + border-radius: 4px; + padding: 2px 10px; + font-size: 12px; + border-width: 1px; + border-style: solid; +} + +.online { + color: #67c23a; + background-color: #f0f9eb; + border-color: #e1f3d8; +} + +.offline { + color: #f56c6c; + background-color: #fef0f0; + border-color: #fde2e2; +} + @media (prefers-color-scheme: dark) { .layui-bg-blue { background-color: #395c74 !important; @@ -152,4 +181,16 @@ .layui-nav-tree .layui-nav-bar { background-color: #4f80a1; } + + .online { + color: #67c23a; + background-color: #1c2518; + border-color: #25371c; + } + + .offline { + color: #f56c6c; + background-color: #2b1d1d; + border-color: #412626; + } } \ No newline at end of file diff --git a/assets/static/css/index.css b/assets/static/css/index.css index 4dc1af2..d64f2bf 100644 --- a/assets/static/css/index.css +++ b/assets/static/css/index.css @@ -25,6 +25,10 @@ section { .layui-side-scroll { width: 245px !important; + position: absolute !important; + top: 0 !important; + bottom: 24px !important; + height: auto !important; } .layui-logo { @@ -37,7 +41,6 @@ section { right: 0; top: 0; height: 100%; - color: #fff; padding: 0 15px; box-sizing: border-box; } @@ -112,7 +115,7 @@ section.server-info .chart-info { flex: 1; } -section.server-info .text-info{ +section.server-info .text-info { padding: 0 20px; } @@ -126,10 +129,6 @@ section.server-info .text-row .text-col { flex: 1; } -section.server-info .text-row .text-col:first-child { - color: #99a9bf; -} - section.server-info .chart-info { display: flex; flex-direction: column; @@ -151,12 +150,12 @@ section.server-info .chart-info #countPieChart { height: 250px; } -.toggle-proxy-info-arrow{ +.toggle-proxy-info-arrow { display: inline-block; transition-duration: 0.2s; } -.toggle-proxy-info-arrow.open{ +.toggle-proxy-info-arrow.open { transform: rotate(90deg); } @@ -165,10 +164,20 @@ section.server-info .chart-info #countPieChart { padding: 10px; } -.proxy-info .layui-col-xs6 .layui-row{ +.proxy-info .layui-col-xs6 .layui-row { padding: 0; } -#trafficBarChart{ +#trafficBarChart { height: 100%; } + +.version { + height: 24px; + line-height: 24px; + position: absolute; + bottom: 0; + width: 100%; + text-align: center; + font-size: 12px; +} \ No newline at end of file diff --git a/assets/static/js/index-proxy-list.js b/assets/static/js/index-proxy-list.js index 18294a2..baeabc9 100644 --- a/assets/static/js/index-proxy-list.js +++ b/assets/static/js/index-proxy-list.js @@ -32,17 +32,48 @@ var loadProxyInfo = (function ($) { * @param proxyType proxy type */ function renderProxyListTable(data, proxyType) { + proxyType = proxyType.toLowerCase(); + data.forEach(function (temp) { + temp.conf = temp.conf || { + remote_port: 0, + use_encryption: false, + use_compression: false, + custom_domains: null, + subdomain: null, + locations: null, + host_header_rewrite: null + }; + + temp.client_version = temp.client_version || '-'; + temp.conf.custom_domains = temp.conf.custom_domains || '-'; + temp.conf.subdomain = temp.conf.subdomain || '-'; + temp.conf.locations = temp.conf.locations || '-'; + temp.conf.host_header_rewrite = temp.conf.host_header_rewrite || '-'; + + if (temp.conf.custom_domains !== '-') { + temp.conf.custom_domains = JSON.stringify(temp.conf.custom_domains); + } + if (proxyType === 'http') { + temp.conf.remote_port = http_port; + } else if (proxyType === 'https') { + temp.conf.remote_port = https_port; + } + }); var $section = $('#content > section'); var cols = [ {field: 'id', type: 'space', width: 60, align: 'center', templet: '#toggleProxyInfoArrowTemplate'}, - {field: 'name', title: 'Name', sort: true}, + {field: 'name', title: i18n['Name'], sort: true}, { - field: 'port', title: 'Port', width: '12%', sort: true, templet: '{{ d.conf.remote_port }}' + field: 'port', + title: i18n['Port'], + width: '12%', + sort: true, + templet: '{{= d.conf.remote_port }}' }, - {field: 'cur_conns', title: 'Connections', minWidth: 140, width: '12%', sort: true}, + {field: 'cur_conns', title: i18n['Connections'], minWidth: 140, width: '12%', sort: true}, { field: 'today_traffic_in', - title: 'Traffic In', + title: i18n['TrafficIn'], minWidth: 140, width: '12%', sort: true, @@ -52,7 +83,7 @@ var loadProxyInfo = (function ($) { }, { field: 'today_traffic_out', - title: 'Traffic Out', + title: i18n['TrafficOut'], minWidth: 140, width: '12%', sort: true, @@ -60,20 +91,13 @@ var loadProxyInfo = (function ($) { return size(d.today_traffic_out); } }, - {field: 'client_version', title: 'ClientVersion', minWidth: 140, width: '12%', sort: true}, - {field: 'status', title: 'Status', width: '12%', sort: true} - ]; - - proxyType = proxyType.toLowerCase(); - if (proxyType === 'http' || proxyType === 'https') { - data.forEach(function (temp) { - if (proxyType === 'http') { - temp.conf.remote_port = http_port; - } else if (proxyType === 'https') { - temp.conf.remote_port = https_port; + {field: 'client_version', title: i18n['ClientVersion'], minWidth: 140, width: '12%', sort: true}, + { + field: 'status', title: i18n['Status'], width: '12%', sort: true, templet: function (d) { + return '' + i18n[d.status] + ''; } - }); - } + } + ]; var proxyListTable = layui.table.render({ elem: '#proxyListTable', @@ -87,11 +111,17 @@ var loadProxyInfo = (function ($) { var $tr = $('.layui-table-view[lay-id=' + this.id + '] tbody tr'); var expandTrTemplateHtml = $('#expandTrTemplate').html(); for (var i = 0; i < $tr.length; i++) { + var datum = res.data[i]; + var useEncryption = datum.conf.use_encryption; + var useCompression = datum.conf.use_compression; + datum.conf.use_encryption = i18n[useEncryption + '']; + datum.conf.use_compression = i18n[useCompression + '']; + console.log(datum) var html = layui.laytpl(expandTrTemplateHtml).render({ index: i, colspan: cols.length - 1, proxyType: proxyType, - data: res.data[i] + data: datum }); $($tr[i]).after(html); } @@ -141,7 +171,7 @@ var loadProxyInfo = (function ($) { now.setDate(now.getDate() - 1); } layui.layer.open({ - title: 'Traffic Statistics', + title: i18n['TrafficStatistics'], type: 1, content: html, area: ['800px', '400px'], @@ -164,10 +194,14 @@ var loadProxyInfo = (function ($) { html += colorEl + v.seriesName + ': ' + size(v.value) + '
' } return html - }, + } }, legend: { - data: ['Traffic In', 'Traffic Out'], + data: [i18n['TrafficIn'], i18n['TrafficOut']], + textStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + } }, grid: { left: '3%', @@ -178,8 +212,8 @@ var loadProxyInfo = (function ($) { xAxis: [ { type: 'category', - data: dates.reverse(), - }, + data: dates.reverse() + } ], yAxis: [ { @@ -187,22 +221,22 @@ var loadProxyInfo = (function ($) { axisLabel: { formatter: function (value) { return size(value) - }, - }, - }, + } + } + } ], series: [ { - name: 'Traffic In', + name: i18n['TrafficIn'], type: 'bar', data: data.traffic_in.reverse(), }, { - name: 'Traffic Out', + name: i18n['TrafficOut'], type: 'bar', data: data.traffic_out.reverse(), - }, - ], + } + ] }; option && chart.setOption(option); diff --git a/assets/static/js/index-server-info.js b/assets/static/js/index-server-info.js index ce32975..d13d9b7 100644 --- a/assets/static/js/index-server-info.js +++ b/assets/static/js/index-server-info.js @@ -48,18 +48,26 @@ var loadServerInfo = (function ($) { * @param data traffic data */ function renderTrafficChart(data) { - var chartLegend = ['total_traffic_in', 'total_traffic_out']; + var chartLegend = [i18n['TrafficIn'], i18n['TrafficOut']]; var chartData = [ - {value: data.total_traffic_in, name: 'Traffic In'}, - {value: data.total_traffic_out, name: 'Traffic Out'} + {value: data.total_traffic_in, name: i18n['TrafficIn']}, + {value: data.total_traffic_out, name: i18n['TrafficOut']} ]; var chartDom = document.getElementById('trafficPieChart'); var chart = echarts.init(chartDom); var option = { title: { - text: 'Network Traffic', - subtext: 'today', - left: 'center' + text: i18n['NetworkTraffic'], + subtext: i18n['today'], + left: 'center', + textStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + }, + subtextStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + } }, tooltip: { trigger: 'item', @@ -71,6 +79,10 @@ var loadServerInfo = (function ($) { orient: 'vertical', left: 'left', data: chartLegend, + textStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + } }, series: [ { @@ -106,16 +118,25 @@ var loadServerInfo = (function ($) { name: type.toUpperCase(), value: proxies[type] }; - chartLegend.push(type); + chartLegend.push(type.toUpperCase()); chartData.push(temp); } + var chartDom = document.getElementById('countPieChart'); var chart = echarts.init(chartDom); var option = { title: { - text: 'Proxies', - subtext: 'now', - left: 'center' + text: i18n['Proxies'], + subtext: i18n['now'], + left: 'center', + textStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + }, + subtextStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + } }, tooltip: { trigger: 'item', @@ -127,6 +148,10 @@ var loadServerInfo = (function ($) { orient: 'vertical', left: 'left', data: chartLegend, + textStyle: { + textBorderColor: '#fff', + textBorderWidth: 2 + } }, series: [ { diff --git a/assets/static/js/index.js b/assets/static/js/index.js index e269ce4..55b8dc5 100644 --- a/assets/static/js/index.js +++ b/assets/static/js/index.js @@ -2,7 +2,7 @@ var http_port, https_port; (function ($) { $(function () { var langLoading = layui.layer.load() - $.getJSON('/lang').done(function (lang) { + $.getJSON('/lang.json').done(function (lang) { layui.element.on('nav(leftNav)', function (elem) { var id = elem.attr('id'); var title = elem.text(); @@ -23,4 +23,4 @@ var http_port, https_port; layui.layer.close(langLoading); }); }); -})(layui.$); +})(layui.$); \ No newline at end of file diff --git a/assets/templates/index.html b/assets/templates/index.html index 3ac9002..d03ceb3 100644 --- a/assets/templates/index.html +++ b/assets/templates/index.html @@ -68,6 +68,7 @@ +
1.0.0
@@ -287,8 +288,8 @@
- -
Traffic Statistics
+ +
${ .TrafficStatistics }
@@ -297,27 +298,27 @@
-
Name
-
{{= d.data.conf.name }}
+
${ .Name }
+
{{= d.data.name }}
-
Type
-
{{= d.data.conf.type }}
+
${ .Type }
+
{{= d.proxyType.toUpperCase() }}
-
Domains
-
{{= JSON.stringify(d.data.conf.custom_domains) }}
+
${ .Domains }
+
{{= d.data.conf.custom_domains }}
-
SubDomain
+
${ .SubDomain }
{{= d.data.conf.subdomain }}
@@ -325,13 +326,13 @@
-
locations
+
${ .Locations }
{{= d.data.conf.locations }}
-
HostRewrite
+
${ .HostRewrite }
{{= d.data.conf.host_header_rewrite }}
@@ -339,13 +340,13 @@
-
Encryption
+
${ .Encryption }
{{= d.data.conf.use_encryption }}
-
Compression
+
${ .Compression }
{{= d.data.conf.use_compression }}
@@ -353,13 +354,13 @@
-
Last Start
+
${ .LastStart }
{{= d.data.last_start_time }}
-
Last Close
+
${ .LastClose }
{{= d.data.last_close_time }}
@@ -368,27 +369,27 @@
-
Name
-
{{= d.data.conf.name }}
+
${ .Name }
+
{{= d.data.name }}
-
Type
-
{{= d.data.conf.type }}
+
${ .Type }
+
{{= d.proxyType.toUpperCase() }}
-
Addr
-
:{{= d.data.conf.remote_port }}
+
${ .Addr }
+
{{= d.data.conf.remote_port }}
-
Encryption
+
${ .Encryption }
{{= d.data.conf.use_encryption }}
@@ -396,13 +397,13 @@
-
Compression
+
${ .Compression }
{{= d.data.conf.use_compression }}
-
Last Start
+
${ .LastStart }
{{= d.data.last_start_time }}
@@ -410,7 +411,7 @@
-
Last Close
+
${ .LastClose }
{{= d.data.last_close_time }}
diff --git a/config/frps-panel.ini b/config/frps-panel.ini index fa36c15..6915d97 100644 --- a/config/frps-panel.ini +++ b/config/frps-panel.ini @@ -6,10 +6,10 @@ plugin_port = 7200 admin_user = admin admin_pwd = admin ; frp dashboard info -dashboard_addr = 127.0.0.1 +dashboard_addr = frp.yanghuanglin.com dashboard_port = 7500 dashboard_user = admin -dashboard_pwd = admin +dashboard_pwd = 19910621 ; user tokens [users] diff --git a/pkg/server/controller/controller.go b/pkg/server/controller/controller.go index 8c94c32..d7d7213 100644 --- a/pkg/server/controller/controller.go +++ b/pkg/server/controller/controller.go @@ -203,6 +203,18 @@ func (c *HandleController) MakeManagerFunc() func(context *gin.Context) { "ServerInfo": ginI18n.MustGetMessage(context, "Server Info"), "Users": ginI18n.MustGetMessage(context, "Users"), "Proxies": ginI18n.MustGetMessage(context, "Proxies"), + "TrafficStatistics": ginI18n.MustGetMessage(context, "Traffic Statistics"), + "Name": ginI18n.MustGetMessage(context, "Name"), + "Type": ginI18n.MustGetMessage(context, "Type"), + "Domains": ginI18n.MustGetMessage(context, "Domains"), + "SubDomain": ginI18n.MustGetMessage(context, "SubDomain"), + "Locations": ginI18n.MustGetMessage(context, "Locations"), + "HostRewrite": ginI18n.MustGetMessage(context, "HostRewrite"), + "Encryption": ginI18n.MustGetMessage(context, "Encryption"), + "Compression": ginI18n.MustGetMessage(context, "Compression"), + "Addr": ginI18n.MustGetMessage(context, "Addr"), + "LastStart": ginI18n.MustGetMessage(context, "Last Start"), + "LastClose": ginI18n.MustGetMessage(context, "Last Close"), }) } } @@ -243,6 +255,21 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) { "SubdomainsInvalid": ginI18n.MustGetMessage(context, "Subdomains is invalid"), "CommentInvalid": ginI18n.MustGetMessage(context, "Comment is invalid"), "ParamError": ginI18n.MustGetMessage(context, "Param error"), + "Name": ginI18n.MustGetMessage(context, "Name"), + "Port": ginI18n.MustGetMessage(context, "Port"), + "Connections": ginI18n.MustGetMessage(context, "Connections"), + "TrafficIn": ginI18n.MustGetMessage(context, "Traffic In"), + "TrafficOut": ginI18n.MustGetMessage(context, "Traffic Out"), + "ClientVersion": ginI18n.MustGetMessage(context, "Client Version"), + "TrafficStatistics": ginI18n.MustGetMessage(context, "Traffic Statistics"), + "online": ginI18n.MustGetMessage(context, "online"), + "offline": ginI18n.MustGetMessage(context, "offline"), + "true": ginI18n.MustGetMessage(context, "true"), + "false": ginI18n.MustGetMessage(context, "false"), + "NetworkTraffic": ginI18n.MustGetMessage(context, "Network Traffic"), + "today": ginI18n.MustGetMessage(context, "today"), + "now": ginI18n.MustGetMessage(context, "now"), + "Proxies": ginI18n.MustGetMessage(context, "Proxies"), }) } } diff --git a/pkg/server/controller/op.go b/pkg/server/controller/op.go index 43e1aff..49212d2 100644 --- a/pkg/server/controller/op.go +++ b/pkg/server/controller/op.go @@ -47,7 +47,7 @@ func (c *HandleController) Register(rootDir string, engine *gin.Engine) { } group.Static("/static", filepath.Join(assets, "static")) group.GET("/", c.MakeManagerFunc()) - group.GET("/lang", c.MakeLangFunc()) + group.GET("/lang.json", c.MakeLangFunc()) group.GET("/tokens", c.MakeQueryTokensFunc()) group.POST("/add", c.MakeAddTokenFunc()) group.POST("/update", c.MakeUpdateTokensFunc())