mirror of
https://github.com/snltty/linker.git
synced 2025-12-18 09:26:44 +08:00
重构中继
This commit is contained in:
@@ -13,4 +13,6 @@ services:
|
||||
- "/$TRIM_APPDEST_VOL/@appshare/linker-docker/configs:/app/configs"
|
||||
- "/$TRIM_APPDEST_VOL/@appshare/linker-docker/logs:/app/logs"
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
environment:
|
||||
- SNLTTY_LINKER_IS_FNOS=linker
|
||||
@@ -1,5 +1,5 @@
|
||||
v1.9.6
|
||||
2025-12-02 17:20:22
|
||||
2025-12-03 17:37:19
|
||||
1. 一些累计更新,一些BUG修复
|
||||
2. 优化客户端数据同步,减少服务器流量
|
||||
3. 去除cdkey,改为发电解锁中继速度
|
||||
|
||||
@@ -65,13 +65,32 @@ namespace linker.libs
|
||||
|
||||
public static string GetSystemStr()
|
||||
{
|
||||
return $"{SystemName()}-{VersionNumber()}-{RuntimeInformation.OSArchitecture.ToString().ToLower()}";
|
||||
return $"{SystemName()}-{VersionNumber()}-any";
|
||||
}
|
||||
private static string SystemName()
|
||||
{
|
||||
string pattern = @"ikuai|fnos|iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker";
|
||||
return Regex.Match(RuntimeInformation.OSDescription.ToLower(), pattern)?.Value ?? "unknow";
|
||||
string pattern = @"ikuai|fnos|iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|docker|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux";
|
||||
return Regex.Match(GetDesc(), pattern)?.Value ?? "unknow";
|
||||
}
|
||||
private static string GetDesc()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_FNOS")) == false)
|
||||
{
|
||||
return "fnos";
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")) == false)
|
||||
{
|
||||
return "docker";
|
||||
}
|
||||
|
||||
if (File.Exists("/usr/trim/www/static/pong.html"))
|
||||
{
|
||||
return "fnos";
|
||||
}
|
||||
|
||||
return RuntimeInformation.OSDescription.ToLower();
|
||||
}
|
||||
|
||||
private static string VersionNumber()
|
||||
{
|
||||
var version = Environment.OSVersion.Version;
|
||||
@@ -91,34 +110,8 @@ namespace linker.libs
|
||||
_ => $"unknow"
|
||||
};
|
||||
}
|
||||
if (OperatingSystem.IsAndroid())
|
||||
{
|
||||
return version.Major switch
|
||||
{
|
||||
35 => "15",
|
||||
34 => "14",
|
||||
33 => "13",
|
||||
32 => "12L",
|
||||
31 => "12",
|
||||
30 => "11",
|
||||
29 => "10",
|
||||
28 => "9",
|
||||
27 => "8.1",
|
||||
26 => "8.0",
|
||||
25 => "7.1",
|
||||
24 => "7.0",
|
||||
23 => "6.0",
|
||||
22 => "5.1",
|
||||
21 => "5.0",
|
||||
_ => $"unknow"
|
||||
};
|
||||
}
|
||||
if (OperatingSystem.IsLinux())
|
||||
{
|
||||
return $"{version.Major}.x";
|
||||
}
|
||||
|
||||
return version.ToString();
|
||||
return $"any";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using linker.libs.extends;
|
||||
using linker.libs.web;
|
||||
using System.Threading.Tasks;
|
||||
namespace linker.messenger.flow.webapi
|
||||
{
|
||||
public sealed class WebApiSystemsController : IWebApiController
|
||||
|
||||
@@ -226,7 +226,8 @@ namespace linker.messenger.relay.server
|
||||
ConnectionsRatio = connectionNum,
|
||||
BandwidthRatio = Math.Round(diff / 5, 2),
|
||||
Version = VersionHelper.Version,
|
||||
Masters = connections.Select(c => c.Address).ToArray()
|
||||
Masters = connections.Select(c => c.Address).ToArray(),
|
||||
MasterKey = config.MasterKey,
|
||||
};
|
||||
byte[] memory = serializer.Serialize(info);
|
||||
var tasks = connections.Select(c => messengerSender.SendOnly(new MessageRequestWrap
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using linker.libs;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.sforward.messenger;
|
||||
using linker.messenger.signin;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.messenger.sforward.server
|
||||
@@ -15,9 +13,6 @@ namespace linker.messenger.sforward.server
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, SForwardServerNodeReportInfo> reports = new ConcurrentDictionary<string, SForwardServerNodeReportInfo>();
|
||||
|
||||
private readonly ConcurrentQueue<Dictionary<int, long>> trafficQueue = new ConcurrentQueue<Dictionary<int, long>>();
|
||||
private readonly ConcurrentQueue<List<int>> trafficIdsQueue = new ConcurrentQueue<List<int>>();
|
||||
|
||||
private readonly ISerializer serializer;
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly ISForwardServerWhiteListStore sForwardServerWhiteListStore;
|
||||
@@ -97,7 +92,14 @@ namespace linker.messenger.sforward.server
|
||||
|
||||
public async Task<SForwardAddResultInfo> Add(SForwardAddInfo info, SignCacheInfo from)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(info.NodeId)) info.NodeId = sForwardServerNodeStore.Node.Id;
|
||||
if (string.IsNullOrWhiteSpace(info.NodeId))
|
||||
{
|
||||
var nodes = await GetNodes(from.Super, from.UserId, from.MachineId);
|
||||
if (nodes.Count > 0)
|
||||
{
|
||||
info.NodeId = nodes[0].Id;
|
||||
}
|
||||
}
|
||||
if (GetNode(info.NodeId, out var node) == false)
|
||||
{
|
||||
return new SForwardAddResultInfo
|
||||
@@ -118,7 +120,7 @@ namespace linker.messenger.sforward.server
|
||||
return new SForwardAddResultInfo
|
||||
{
|
||||
BufferSize = 1,
|
||||
Message = "white list deney",
|
||||
Message = "white list deny",
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,18 +10,16 @@ namespace linker.messenger.sforward.server.validator
|
||||
public string Name => "default";
|
||||
|
||||
private readonly ISForwardServerStore sForwardServerStore;
|
||||
private readonly SForwardServerMasterTransfer sForwardServerMasterTransfer;
|
||||
private readonly ISForwardServerNodeStore sForwardServerNodeStore;
|
||||
public SForwardValidator(ISForwardServerStore sForwardServerStore, SForwardServerMasterTransfer sForwardServerMasterTransfer, ISForwardServerNodeStore sForwardServerNodeStore)
|
||||
public SForwardValidator(ISForwardServerStore sForwardServerStore, ISForwardServerNodeStore sForwardServerNodeStore)
|
||||
{
|
||||
this.sForwardServerStore = sForwardServerStore;
|
||||
this.sForwardServerMasterTransfer = sForwardServerMasterTransfer;
|
||||
this.sForwardServerNodeStore = sForwardServerNodeStore;
|
||||
}
|
||||
|
||||
public async Task<string> Validate(SignCacheInfo signCacheInfo, SForwardAddInfo sForwardAddInfo)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sForwardAddInfo.NodeId)) sForwardAddInfo.NodeId = sForwardServerNodeStore.Node.Id;
|
||||
//if (string.IsNullOrWhiteSpace(sForwardAddInfo.NodeId)) sForwardAddInfo.NodeId = sForwardServerNodeStore.Node.Id;
|
||||
|
||||
if (sForwardAddInfo.RemotePort > 0)
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace linker.messenger.store.file.relay
|
||||
MasterKey = info.MasterKey,
|
||||
Masters = info.Masters,
|
||||
//是我初始化的,可以管理
|
||||
Manageable = info.MasterKey == md5
|
||||
Manageable = false//info.MasterKey == md5
|
||||
}, c => c.NodeId == info.NodeId);
|
||||
|
||||
return await Task.FromResult(length > 0).ConfigureAwait(false); ;
|
||||
|
||||
@@ -243,6 +243,9 @@
|
||||
<a href="" class="linker-download block px-4 py-1.5 text-sm hover:bg-light-dark rounded transition-colors" data-file="linker-docker-x64.fpk">
|
||||
<i class="fa fa-linux mr-2 text-accent"></i> x64 (Docker)
|
||||
</a>
|
||||
<a href="" class="linker-download block px-4 py-1.5 text-sm hover:bg-light-dark rounded transition-colors" data-file="linker-bin-x64.fpk">
|
||||
<i class="fa fa-linux mr-2 text-accent"></i> x64 (Binary)
|
||||
</a>
|
||||
</div>
|
||||
<!-- OpenWRT 下载链接 -->
|
||||
<div class="border-b border-light-dark pb-1 mb-1 download-openwrt">
|
||||
|
||||
@@ -235,6 +235,9 @@
|
||||
<a href="" class="linker-download block px-4 py-1.5 text-sm hover:bg-light-dark rounded transition-colors" data-file="linker-docker-x64.fpk">
|
||||
<i class="fa fa-linux mr-2 text-accent"></i> x64 (Docker)
|
||||
</a>
|
||||
<a href="" class="linker-download block px-4 py-1.5 text-sm hover:bg-light-dark rounded transition-colors" data-file="linker-bin-x64.fpk">
|
||||
<i class="fa fa-linux mr-2 text-accent"></i> x64 (Binary)
|
||||
</a>
|
||||
</div>
|
||||
<!-- OpenWRT 下载链接 -->
|
||||
<div class="border-b border-light-dark pb-1 mb-1 download-openwrt">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.350" ProductVersion="0.0.0.350" publishDir="/dist/" dstrip="false" local="false" ignored="false">
|
||||
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.352" ProductVersion="0.0.0.352" publishDir="/dist/" dstrip="false" local="false" ignored="false">
|
||||
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
|
||||
<folder name="资源文件" path="res" embed="true" local="false" ignored="false">
|
||||
<file name="favicon.ico" path="res\favicon.ico" comment="res\favicon.ico"/>
|
||||
|
||||
BIN
src/linker.tray.win/dist/linker.tray.win.exe
vendored
BIN
src/linker.tray.win/dist/linker.tray.win.exe
vendored
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
import win.ui;
|
||||
/*DSG{{*/
|
||||
var winform = win.form(text="linker 管理";right=820;bottom=750;max=false)
|
||||
var winform = win.form(text="linker 管理";right=820;bottom=820;max=false)
|
||||
winform.add()
|
||||
/*}}*/
|
||||
|
||||
|
||||
@@ -202,6 +202,7 @@ export default {
|
||||
'server.relayPublic': 'Public',
|
||||
'server.relayAllow': 'Allow',
|
||||
'server.relayUrl': 'Url',
|
||||
'server.relayLogo': 'Logo',
|
||||
'server.relayOper': 'Oper',
|
||||
'server.relayUse': 'Use',
|
||||
'server.relayDefault': 'Default',
|
||||
|
||||
@@ -298,6 +298,7 @@ export default {
|
||||
'server.relayPublic': '公开',
|
||||
'server.relayAllow': '支持协议',
|
||||
'server.relayUrl': 'Url',
|
||||
'server.relayLogo': 'Logo',
|
||||
'server.relayOper': '操作',
|
||||
'server.relayUse': '使用',
|
||||
'server.relayDefault': '默认',
|
||||
|
||||
@@ -3,35 +3,35 @@
|
||||
<div>
|
||||
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
|
||||
<el-form-item :label="$t('server.relayName')" prop="Name">
|
||||
<el-input v-trim minlength="1" maxlength="32" show-word-limit v-model="state.ruleForm.Name" />
|
||||
<el-input :disabled="data.Manageable==false" v-trim minlength="1" maxlength="32" show-word-limit v-model="state.ruleForm.Name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayConnection')" prop="MaxConnection">
|
||||
<el-input-number v-model="state.ruleForm.MaxConnection" :min="0" :max="65535"/>
|
||||
<el-form-item :label="$t('server.relayConnection')" prop="Connections">
|
||||
<el-input-number :disabled="data.Manageable==false" v-model="state.ruleForm.Connections" :min="0" :max="65535"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relaySpeed')" prop="MaxBandwidth">
|
||||
<el-input-number v-model="state.ruleForm.MaxBandwidth" :min="0"/>Mbps
|
||||
<el-form-item :label="$t('server.relaySpeed')" prop="BandwidthEach">
|
||||
<el-input-number v-model="state.ruleForm.BandwidthEach" :min="0"/>Mbps
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relaySpeed1')" prop="MaxBandwidthTotal">
|
||||
<el-input-number v-model="state.ruleForm.MaxBandwidthTotal" :min="0"/>Mbps
|
||||
<el-form-item :label="$t('server.relaySpeed1')" prop="Bandwidth">
|
||||
<el-input-number :disabled="data.Manageable==false" v-model="state.ruleForm.Bandwidth" :min="0"/>Mbps
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayFlow')" prop="MaxGbTotal">
|
||||
<el-input-number v-model="state.ruleForm.MaxGbTotal" :min="0"/>GB <el-button size="small" @click="handleRefresh"><el-icon><Refresh /></el-icon></el-button>
|
||||
<el-form-item :label="$t('server.relayFlow')" prop="DataEachMonth">
|
||||
<el-input-number :disabled="data.Manageable==false" v-model="state.ruleForm.DataEachMonth" :min="0"/>GB <el-button size="small" @click="handleRefresh"><el-icon><Refresh /></el-icon></el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayFlowLast')" prop="MaxGbTotalLastBytes">
|
||||
<el-input-number v-model="state.ruleForm.MaxGbTotalLastBytes" :min="0" />byte
|
||||
<el-form-item :label="$t('server.relayFlowLast')" prop="DataRemain">
|
||||
<el-input-number :disabled="data.Manageable==false" v-model="state.ruleForm.DataRemain" :min="0" />byte
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayUrl')" prop="Url">
|
||||
<el-input v-trim v-model="state.ruleForm.Url" />
|
||||
<el-input :disabled="data.Manageable==false" v-trim v-model="state.ruleForm.Url" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayLogo')" prop="Logo">
|
||||
<el-input :disabled="data.Manageable==false" v-trim v-model="state.ruleForm.Logo" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayPublic')" prop="Public">
|
||||
<el-switch v-model="state.ruleForm.Public " size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relaySync2Server')" prop="Sync2Server">
|
||||
<el-switch v-model="state.ruleForm.Sync2Server " size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('server.relayAllow')" prop="Allow">
|
||||
<el-checkbox v-model="state.ruleForm.AllowTcp">TCP</el-checkbox>
|
||||
<el-checkbox v-model="state.ruleForm.AllowUdp">UDP</el-checkbox>
|
||||
<el-checkbox :disabled="data.Manageable==false" v-model="state.ruleForm.AllowTcp">TCP</el-checkbox>
|
||||
<el-checkbox :disabled="data.Manageable==false" v-model="state.ruleForm.AllowUdp">UDP</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item></el-form-item>
|
||||
<el-form-item label="" prop="Btns">
|
||||
@@ -62,16 +62,16 @@ export default {
|
||||
ruleForm:{
|
||||
Id:props.data.Id,
|
||||
Name:props.data.Name,
|
||||
MaxConnection:props.data.MaxConnection,
|
||||
MaxBandwidth:props.data.MaxBandwidth,
|
||||
MaxBandwidthTotal:props.data.MaxBandwidthTotal,
|
||||
MaxGbTotal:props.data.MaxGbTotal,
|
||||
MaxGbTotalLastBytes:props.data.MaxGbTotalLastBytes,
|
||||
Connections:props.data.Connections,
|
||||
BandwidthEach:props.data.BandwidthEach,
|
||||
Bandwidth:props.data.Bandwidth,
|
||||
DataEachMonth:props.data.DataEachMonth,
|
||||
DataRemain:props.data.DataRemain,
|
||||
Public:props.data.Public,
|
||||
Url:props.data.Url,
|
||||
AllowTcp:(props.data.AllowProtocol & 1) == 1,
|
||||
AllowUdp:(props.data.AllowProtocol & 2) == 2,
|
||||
Sync2Server:props.data.Sync2Server || false,
|
||||
Logo:props.data.Logo,
|
||||
AllowTcp:(props.data.Protocol & 1) == 1,
|
||||
AllowUdp:(props.data.Protocol & 2) == 2,
|
||||
},
|
||||
rules:{
|
||||
}
|
||||
@@ -84,7 +84,7 @@ export default {
|
||||
}
|
||||
});
|
||||
const handleRefresh = ()=>{
|
||||
state.ruleForm.MaxGbTotalLastBytes = state.ruleForm.MaxGbTotal * 1024*1024*1024;
|
||||
state.ruleForm.DataRemain = state.ruleForm.DataEachMonth * 1024*1024*1024;
|
||||
}
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
@@ -93,7 +93,7 @@ export default {
|
||||
if (!valid) return;
|
||||
|
||||
const json = JSON.parse(JSON.stringify(state.ruleForm));
|
||||
json.AllowProtocol = (json.AllowTcp ? 1 : 0) | (json.AllowUdp ? 2 : 0);
|
||||
json.Protocol = (json.AllowTcp ? 1 : 0) | (json.AllowUdp ? 2 : 0);
|
||||
|
||||
relayEdit(json).then((res)=>{
|
||||
if(res){
|
||||
|
||||
@@ -5,82 +5,85 @@
|
||||
<el-table :data="state.nodes" size="small" border height="500" stripe>
|
||||
<el-table-column property="Name" :label="$t('server.relayName')">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<p class="flex">
|
||||
<a :href="scope.row.Url" class="a-line"
|
||||
:class="{green:scope.row.Public}" target="_blank"
|
||||
:title="scope.row.Public?$t('server.relayPublic'):''"><strong>{{ scope.row.Name }}</strong></a>
|
||||
<span class="flex-1"></span>
|
||||
<a href="javascript:;">
|
||||
<span v-if="(scope.row.AllowProtocol & 1) == 1">tcp</span>
|
||||
<span v-if="(scope.row.AllowProtocol & 2) == 2">,udp</span>
|
||||
<div class="flex">
|
||||
<div>
|
||||
<a :href="scope.row.Url" target="_blank" >
|
||||
<img class="logo" :src="scope.row.Logo || 'https://linker.snltty.com/img/logo.png'" alt=""/>
|
||||
</a>
|
||||
</p>
|
||||
<p class="flex">
|
||||
<el-checkbox v-if="state.super" class="mgr-p6" v-model="scope.row.Sync2Server" disabled size="small" @click="handleSync2Server(scope.row)">{{ $t('server.relaySync2Server') }}</el-checkbox>
|
||||
<template v-if="(scope.row.AllowProtocol & 1) == 1">
|
||||
<template v-if="state.syncData.Key == scope.row.Id && state.syncData.Value == 1">
|
||||
<el-checkbox class="mgr-p6" size="small" disabled checked>{{ $t('server.relayDefault') }}TCP</el-checkbox>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-checkbox class="mgr-p6" size="small" disabled @click.stop="handleShowSync(scope.row.Id, 1)">{{ $t('server.relayDefault') }}TCP</el-checkbox>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="(scope.row.AllowProtocol & 2) == 2">
|
||||
<template v-if="state.syncData.Key == scope.row.Id && state.syncData.Value == 2">
|
||||
<el-checkbox class="mgr-p6" size="small" disabled checked>{{ $t('server.relayDefault') }}UDP</el-checkbox>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-checkbox class="mgr-p6" size="small" disabled @click.stop="handleShowSync(scope.row.Id, 2)">{{ $t('server.relayDefault') }}UDP</el-checkbox>
|
||||
</template>
|
||||
</template>
|
||||
<span class="flex-1"></span>
|
||||
<a v-if="state.super" href="javascript:;" class="a-line a-edit" @click="handleUpdate(scope.row.Id)"><el-icon><Refresh /></el-icon>{{ scope.row.Version }}</a>
|
||||
<a v-else href="javascript:;" class="a-line a-edit"><el-icon><Refresh /></el-icon>{{ scope.row.Version }}</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="flex">
|
||||
<a :href="scope.row.Url" class="a-line"
|
||||
:class="{green:scope.row.Public}" target="_blank"
|
||||
:title="scope.row.Public?$t('server.relayPublic'):''"><strong>{{ scope.row.Name }}</strong></a>
|
||||
<span class="flex-1"></span>
|
||||
<a href="javascript:;" class="protocol">
|
||||
<span v-if="(scope.row.Protocol & 1) == 1">tcp</span>
|
||||
<span v-if="(scope.row.Protocol & 2) == 2">,udp</span>
|
||||
</a>
|
||||
|
||||
</p>
|
||||
<p class="flex">
|
||||
<div>
|
||||
<template v-if="state.syncData.Key == scope.row.Id">
|
||||
<el-checkbox size="small" disabled checked>{{ $t('server.relayDefault') }}</el-checkbox>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-checkbox size="small" disabled @click.stop="handleShowSync(scope.row, 1)">{{ $t('server.relayDefault') }}</el-checkbox>
|
||||
</template>
|
||||
</div>
|
||||
<span class="flex-1"></span>
|
||||
<a v-if="state.super" href="javascript:;" class="a-line a-edit" @click="handleUpdate(scope.row)"><el-icon><Refresh /></el-icon>{{ scope.row.Version }}</a>
|
||||
<a v-else href="javascript:;" class="a-line a-edit"><el-icon><Refresh /></el-icon>{{ scope.row.Version }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="MaxGbTotal" :label="$t('server.relayFlow')" width="100">
|
||||
<el-table-column property="ConnectionsRatio" :label="$t('server.relayConnection')" width="80">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.MaxGbTotal == 0">--</template>
|
||||
<p>
|
||||
<template v-if="scope.row.Connections == 0">--</template>
|
||||
<template v-else>{{ scope.row.Connections }}</template>
|
||||
</p>
|
||||
<p><strong>{{scope.row.ConnectionsRatio}}</strong></p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="Bandwidth" :label="$t('server.relaySpeed1')" width="100">
|
||||
<template #default="scope">
|
||||
<p>
|
||||
<template v-if="scope.row.Bandwidth == 0">--</template>
|
||||
<template v-else>{{ scope.row.Bandwidth }}Mbps</template>
|
||||
</p>
|
||||
<p><strong>{{scope.row.BandwidthRatio}}Mbps</strong></p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="DataEachMonth" :label="$t('server.relayFlow')" width="100">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.DataEachMonth == 0">
|
||||
<p>--</p>
|
||||
<p>--</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>{{ scope.row.MaxGbTotal }}GB</p>
|
||||
<p><strong>{{ (scope.row.MaxGbTotalLastBytes/1024/1024/1024).toFixed(2) }}GB</strong></p>
|
||||
<p>{{ scope.row.DataEachMonth }}GB</p>
|
||||
<p><strong>{{ (scope.row.DataRemain/1024/1024/1024).toFixed(2) }}GB</strong></p>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="MaxBandwidth" :label="$t('server.relaySpeed')" width="80">
|
||||
<el-table-column property="BandwidthEach" :label="$t('server.relaySpeed')" width="80">
|
||||
<template #default="scope">
|
||||
<p>
|
||||
<span v-if="scope.row.MaxBandwidth == 0">--</span>
|
||||
<span v-else>{{ scope.row.MaxBandwidth }}Mbps</span>
|
||||
<span v-if="scope.row.BandwidthEach == 0">--</span>
|
||||
<span v-else>{{ scope.row.BandwidthEach }}Mbps</span>
|
||||
</p>
|
||||
<p>{{ scope.row.Delay }}ms</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="MaxBandwidthTotal" :label="$t('server.relaySpeed1')" width="100">
|
||||
<el-table-column v-if="state.super" property="Manageable" :label="$t('server.relayOper')" width="110">
|
||||
<template #default="scope">
|
||||
<p>
|
||||
<template v-if="scope.row.MaxBandwidthTotal == 0">--</template>
|
||||
<template v-else>{{ scope.row.MaxBandwidthTotal }}Mbps</template>
|
||||
</p>
|
||||
<p><strong>{{scope.row.BandwidthRatio}}mbps</strong></p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="ConnectionRatio" :label="$t('server.relayConnection')" width="80">
|
||||
<template #default="scope">
|
||||
<p>{{scope.row.MaxConnection}}</p>
|
||||
<p><strong>{{scope.row.ConnectionRatio}}</strong></p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="state.super" property="Public" :label="$t('server.relayOper')" width="60">
|
||||
<template #default="scope">
|
||||
<p>
|
||||
<a href="javascript:;" class="a-line" @click="handleExit(scope.row.Id)"><el-icon><Refresh /></el-icon>{{ $t('server.relayExit') }}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="javascript:;" class="a-line" @click="handleEdit(scope.row)"><el-icon><Edit /></el-icon>{{ $t('server.relayEdit') }}</a>
|
||||
<el-button v-if="scope.row.Manageable" size="small" @click="handleExit(scope.row)"><el-icon><Refresh /></el-icon></el-button>
|
||||
<el-button size="small" @click="handleEdit(scope.row)"><el-icon><Edit /></el-icon></el-button>
|
||||
</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -93,7 +96,7 @@
|
||||
<div class="t-c">{{ $t('server.relaySetDefaultText') }}</div>
|
||||
<Ids ref="domIds"></Ids>
|
||||
<div class="t-c w-100 mgt-1">
|
||||
<el-button @click="state.showSync = false">{{$t('common.cancel')}}</el-button>
|
||||
<el-button @click="handleCancelSync">{{$t('common.cancel')}}</el-button>
|
||||
<el-button type="primary" @click="handleSync">{{$t('common.confirm')}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -138,13 +141,20 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
const _getDefault = ()=>{
|
||||
getDefault().then((res)=>{
|
||||
state.syncData.Key = res.Key || '';
|
||||
state.syncData.Value = res.Value || 0;
|
||||
});
|
||||
}
|
||||
|
||||
const handleEdit = (row)=>{
|
||||
state.current = row;
|
||||
state.showEdit = true;
|
||||
}
|
||||
const domIds = ref(null);
|
||||
const handleShowSync = (id,proto)=>{
|
||||
state.syncData.Key = id;
|
||||
const handleShowSync = (row,proto)=>{
|
||||
state.syncData.Key = row.Id;
|
||||
state.syncData.Value = proto;
|
||||
state.showSync = true;
|
||||
}
|
||||
@@ -155,10 +165,16 @@ export default {
|
||||
}).then((res)=>{
|
||||
state.showSync = false;
|
||||
ElMessage.success(t('common.oper'));
|
||||
_getDefault();
|
||||
}).catch(()=>{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
_getDefault();
|
||||
//ElMessage.error(t('common.operFail'));
|
||||
});
|
||||
}
|
||||
const handleCancelSync = ()=>{
|
||||
state.showSync = false;
|
||||
_getDefault();
|
||||
}
|
||||
|
||||
const handleSync2Server = (row)=>{
|
||||
row.Sync2Server = !row.Sync2Server;
|
||||
@@ -170,13 +186,13 @@ export default {
|
||||
ElMessage.error(t('common.operFail'));
|
||||
});
|
||||
}
|
||||
const handleExit = (id)=>{
|
||||
const handleExit = (row)=>{
|
||||
ElMessageBox.confirm(t('server.relayExit'), t('common.confirm'), {
|
||||
confirmButtonText: t('common.confirm'),
|
||||
cancelButtonText: t('common.cancel'),
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
relayExit(id).then(res => {
|
||||
relayExit(row.Id).then(res => {
|
||||
ElMessage.success(t('common.oper'));
|
||||
}).catch(()=>{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
@@ -185,13 +201,14 @@ export default {
|
||||
ElMessage.error(t('common.operFail'));
|
||||
});
|
||||
}
|
||||
const handleUpdate = (id)=>{
|
||||
const handleUpdate = (row)=>{
|
||||
if(row.Manageable == false) return;
|
||||
ElMessageBox.confirm(`${t('server.relayUpdate')} ${globalData.value.signin.Version}`,t('server.relayUpdate'), {
|
||||
confirmButtonText: t('common.confirm'),
|
||||
cancelButtonText: t('common.cancel'),
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
relayUpdate({Key:id,Value:globalData.value.signin.Version}).then(res => {
|
||||
relayUpdate({Key:row.Id,Value:globalData.value.signin.Version}).then(res => {
|
||||
ElMessage.success(t('common.oper'));
|
||||
}).catch(()=>{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
@@ -202,16 +219,15 @@ export default {
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
getDefault().then((res)=>{
|
||||
state.syncData.Key = res.Key || '';
|
||||
state.syncData.Value = res.Value || 0;
|
||||
});
|
||||
_getDefault();
|
||||
});
|
||||
onUnmounted(()=>{
|
||||
clearTimeout(state.timer);
|
||||
});
|
||||
|
||||
return {globalData,state,handleEdit,domIds,handleShowSync,handleSync,handleExit,handleUpdate,handleSync2Server}
|
||||
return {globalData,state,
|
||||
handleEdit,domIds,handleShowSync,handleSync,handleCancelSync,
|
||||
handleExit,handleUpdate,handleSync2Server}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -225,4 +241,9 @@ a.a-edit{
|
||||
vertical-align middle
|
||||
}
|
||||
}
|
||||
.logo{
|
||||
margin-right:1rem;
|
||||
height:4rem;
|
||||
vertical-align:text-top;
|
||||
}
|
||||
</style>
|
||||
@@ -67,31 +67,29 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="MaxGbTotal" :label="$t('server.relayFlow')" width="100">
|
||||
<el-table-column property="ConnectionsRatio" :label="$t('server.relayConnection')" width="80">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.MaxGbTotal == 0">--</span>
|
||||
<span><strong>{{ scope.row.ConnectionsRatio }}</strong></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="BandwidthEach" :label="$t('server.relaySpeed')" width="140">
|
||||
<template #default="scope">
|
||||
<p>
|
||||
<span>{{ scope.row.BandwidthRatio }}Mbps</span>
|
||||
<span> / </span>
|
||||
<span v-if="scope.row.BandwidthEach == 0">--</span>
|
||||
<span v-else>{{ scope.row.BandwidthEach }}Mbps</span>
|
||||
</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="DataEachMonth" :label="$t('server.relayFlow')" width="100">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.DataEachMonth == 0">--</span>
|
||||
<span v-else>
|
||||
{{ (scope.row.MaxGbTotalLastBytes / 1024 / 1024 / 1024).toFixed(2) }}GB
|
||||
{{ (scope.row.DataRemain / 1024 / 1024 / 1024).toFixed(2) }}GB
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="MaxBandwidth" :label="$t('server.relaySpeed')" width="80">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.MaxBandwidth == 0">--</span>
|
||||
<span v-else>{{ scope.row.MaxBandwidth }}Mbps</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="MaxBandwidthTotal"
|
||||
:label="$t('server.relaySpeed2')" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.BandwidthRatio }}Mbps</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="ConnectionRatio" :label="$t('server.relayConnection')" width="80">
|
||||
<template #default="scope">
|
||||
<span><strong>{{ scope.row.ConnectionRatio }}</strong></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="Delay" :label="$t('server.relayDelay')" width="60">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.Delay }}ms</span>
|
||||
@@ -104,8 +102,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column property="Oper" :label="$t('server.relayUse')" width="130">
|
||||
<template #default="scope">
|
||||
<el-button size="small" v-if="(scope.row.AllowProtocol & 1) == 1" @click="handleConnect(scope.row.Id, 1)">TCP</el-button>
|
||||
<el-button size="small" v-if="(scope.row.AllowProtocol & 2) == 2" @click="handleConnect(scope.row.Id, 2)">UDP</el-button>
|
||||
<el-button size="small" v-if="(scope.row.Protocol & 1) == 1" @click="handleConnect(scope.row, 1)">TCP</el-button>
|
||||
<el-button size="small" v-if="(scope.row.Protocol & 2) == 2" @click="handleConnect(scope.row, 2)">UDP</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -189,12 +187,12 @@ export default {
|
||||
const handleNode = () => {
|
||||
state.showNodes = true;
|
||||
}
|
||||
const handleConnect = (id, protocol) => {
|
||||
const handleConnect = (row, protocol) => {
|
||||
const json = {
|
||||
FromMachineId: globalData.value.config.Client.Id,
|
||||
TransactionId: state.transactionId,
|
||||
ToMachineId: state.device.MachineId,
|
||||
NodeId: id,
|
||||
NodeId: row.NodeId,
|
||||
Protocol: protocol
|
||||
};
|
||||
relayConnect(json).then(() => {ElMessage.success(t('common.oper')); }).catch(() => {ElMessage.success(t('common.operFail')); });
|
||||
|
||||
@@ -20,6 +20,8 @@ RUN apt update \
|
||||
|
||||
EXPOSE 1802/tcp
|
||||
EXPOSE 1802/udp
|
||||
EXPOSE 1803/tcp
|
||||
EXPOSE 1803/udp
|
||||
EXPOSE 1804/tcp
|
||||
EXPOSE 1804/udp
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ RUN apt update \
|
||||
|
||||
EXPOSE 1802/tcp
|
||||
EXPOSE 1802/udp
|
||||
EXPOSE 1803/tcp
|
||||
EXPOSE 1803/udp
|
||||
EXPOSE 1804/tcp
|
||||
EXPOSE 1804/udp
|
||||
EXPOSE 1806/tcp
|
||||
|
||||
@@ -10,6 +10,8 @@ RUN echo "https://mirrors.ustc.edu.cn/alpine/latest-stable/main/" > /etc/apk/rep
|
||||
|
||||
EXPOSE 1802/tcp
|
||||
EXPOSE 1802/udp
|
||||
EXPOSE 1803/tcp
|
||||
EXPOSE 1803/udp
|
||||
EXPOSE 1804/tcp
|
||||
EXPOSE 1804/udp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user