This commit is contained in:
snltty
2025-03-08 19:25:04 +08:00
parent 0d1e62f07d
commit 342dbe5e8c
22 changed files with 633 additions and 199 deletions

View File

@@ -14,7 +14,10 @@ class Demo extends ManagePlugin
#[Hook(point: \App\Consts\Hook::USER_API_ORDER_PAY_AFTER)] #[Hook(point: \App\Consts\Hook::USER_API_ORDER_PAY_AFTER)]
public function tradeAfter($commodity, $order, $pay) public function tradeAfter($commodity, $order, $pay)
{ {
$secret = json_decode($order->secret,true); $lines = array_map(function($line) {
return rtrim($line, "\r");
}, explode("\n", $order->secret));
$secret = json_decode($lines[0],true);
try{ try{
$widget = json_decode($order->widget,true); $widget = json_decode($order->widget,true);
@@ -32,13 +35,12 @@ class Demo extends ManagePlugin
$secret["PayPrice"] = $order["amount"]; $secret["PayPrice"] = $order["amount"];
$secret["Count"] = $order["card_num"]; $secret["Count"] = $order["card_num"];
$order->secret = json_encode($secret,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $order->secret = json_encode($secret,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
//file_put_contents("secret.txt",$order->secret);
$config = Plugin::getConfig("Demo"); $config = Plugin::getConfig("Demo");
$aesCrypto = new AesCrypto($config["KeyId"]); $aesCrypto = new AesCrypto($config["KeyId"]);
$order->secret = base64_encode($aesCrypto->encode($order->secret)); $order->secret = base64_encode($aesCrypto->encode($order->secret));
$order->save(); $order->save();
} }
} }
class AesCrypto class AesCrypto
{ {

Binary file not shown.

View File

@@ -28,6 +28,8 @@
TestCdkey = 2115, TestCdkey = 2115,
ImportCdkey = 2116, ImportCdkey = 2116,
UpdateNode = 2117,
Max = 2199 Max = 2199
} }
} }

View File

@@ -82,6 +82,7 @@
public string SecretKey { get; set; } public string SecretKey { get; set; }
public RelayServerCdkeyPageRequestFlag Flag { get; set; } public RelayServerCdkeyPageRequestFlag Flag { get; set; }
} }
[Flags]
public enum RelayServerCdkeyPageRequestFlag public enum RelayServerCdkeyPageRequestFlag
{ {
All = 0, All = 0,

View File

@@ -23,6 +23,7 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
/// <param name="node"></param> /// <param name="node"></param>
public void SetInfo(RelayServerNodeInfo node); public void SetInfo(RelayServerNodeInfo node);
public void UpdateInfo(RelayServerNodeUpdateInfo update);
/// <summary> /// <summary>
/// 设置月份 /// 设置月份
@@ -81,6 +82,17 @@ namespace linker.messenger.relay.server
#endif #endif
} }
public sealed partial class RelayServerNodeUpdateInfo
{
public string Name { get; set; } = string.Empty;
public int MaxConnection { get; set; }
public double MaxBandwidth { get; set; }
public double MaxBandwidthTotal { get; set; }
public double MaxGbTotal { get; set; }
public long MaxGbTotalLastBytes { get; set; }
public bool Public { get; set; }
}
public sealed partial class RelayServerNodeReportInfo public sealed partial class RelayServerNodeReportInfo
{ {
public string Id { get; set; } = string.Empty; public string Id { get; set; } = string.Empty;
@@ -104,7 +116,6 @@ namespace linker.messenger.relay.server
public long LastTicks { get; set; } public long LastTicks { get; set; }
} }
public sealed partial class RelayAskResultInfo public sealed partial class RelayAskResultInfo
{ {
public ulong FlowingId { get; set; } public ulong FlowingId { get; set; }

View File

@@ -376,12 +376,12 @@ namespace linker.messenger.relay.server
Name = node.Name, Name = node.Name,
Public = node.Public, Public = node.Public,
MaxBandwidth = node.MaxBandwidth, MaxBandwidth = node.MaxBandwidth,
BandwidthRatio = Math.Round(node.MaxBandwidthTotal == 0 ? 0 : diff / 5 / node.MaxBandwidthTotal, 2), BandwidthRatio = Math.Round(diff / 5, 2),
MaxBandwidthTotal = node.MaxBandwidthTotal, MaxBandwidthTotal = node.MaxBandwidthTotal,
MaxGbTotal = node.MaxGbTotal, MaxGbTotal = node.MaxGbTotal,
MaxGbTotalLastBytes = node.MaxGbTotalLastBytes, MaxGbTotalLastBytes = node.MaxGbTotalLastBytes,
MaxConnection = node.MaxConnection, MaxConnection = node.MaxConnection,
ConnectionRatio = Math.Round(node.MaxConnection == 0 ? 0 : connectionNum / 2.0 / node.MaxConnection, 2), ConnectionRatio = Math.Round(connectionNum / 2.0),
EndPoint = endPoint EndPoint = endPoint
}; };

View File

@@ -51,6 +51,7 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new RelayTestInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayTestInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());

View File

@@ -150,6 +150,78 @@ namespace linker.messenger.serializer.memorypack
} }
} }
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeUpdateInfo
{
[MemoryPackIgnore]
public readonly RelayServerNodeUpdateInfo info;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
int MaxConnection => info.MaxConnection;
[MemoryPackInclude]
double MaxBandwidth => info.MaxBandwidth;
[MemoryPackInclude]
double MaxBandwidthTotal => info.MaxBandwidthTotal;
[MemoryPackInclude]
double MaxGbTotal => info.MaxGbTotal;
[MemoryPackInclude]
long MaxGbTotalLastBytes => info.MaxGbTotalLastBytes;
[MemoryPackInclude]
bool Public => info.Public;
[MemoryPackConstructor]
SerializableRelayServerNodeUpdateInfo(
string name,
int maxConnection, double maxBandwidth, double maxBandwidthTotal,
double maxGbTotal, long maxGbTotalLastBytes,
bool Public)
{
var info = new RelayServerNodeUpdateInfo
{
MaxBandwidth = maxBandwidth,
MaxBandwidthTotal = maxBandwidthTotal,
MaxConnection = maxConnection,
MaxGbTotal = maxGbTotal,
MaxGbTotalLastBytes = maxGbTotalLastBytes,
Name = name,
Public = Public
};
this.info = info;
}
public SerializableRelayServerNodeUpdateInfo(RelayServerNodeUpdateInfo info)
{
this.info = info;
}
}
public class RelayServerNodeUpdateInfoFormatter : MemoryPackFormatter<RelayServerNodeUpdateInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeUpdateInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeUpdateInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeUpdateInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerNodeUpdateInfo>();
value = wrapped.info;
}
}
[MemoryPackable] [MemoryPackable]

View File

@@ -29,6 +29,7 @@ namespace linker.messenger.store.file.relay
info.Id = ObjectId.NewObjectId().ToString(); info.Id = ObjectId.NewObjectId().ToString();
info.AddTime = DateTime.Now; info.AddTime = DateTime.Now;
info.UseTime = DateTime.Now; info.UseTime = DateTime.Now;
info.StartTime = DateTime.Now;
info.LastBytes = info.MaxBytes; info.LastBytes = info.MaxBytes;
info.CdkeyId = YitIdHelper.NextId(); info.CdkeyId = YitIdHelper.NextId();
info.OrderId = $"Linker{YitIdHelper.NextId()}"; info.OrderId = $"Linker{YitIdHelper.NextId()}";
@@ -60,7 +61,7 @@ namespace linker.messenger.store.file.relay
RelayServerCdkeyOrderInfo order = result.Cdkey.DeJson<RelayServerCdkeyOrderInfo>(); RelayServerCdkeyOrderInfo order = result.Cdkey.DeJson<RelayServerCdkeyOrderInfo>();
result.Order = order; result.Order = order;
if (order.WidgetUserId != info.UserId) if (order.WidgetUserId != info.UserId || string.IsNullOrWhiteSpace(order.WidgetUserId))
{ {
error.Add("UserId"); error.Add("UserId");
} }
@@ -106,36 +107,33 @@ namespace linker.messenger.store.file.relay
} }
RelayServerCdkeyOrderInfo order = test.Order; RelayServerCdkeyOrderInfo order = test.Order;
var time = Regex.Match(order.Time, regex).Groups; var time = Regex.Match(order.Time, regex).Groups;
for (int i = 0; i < order.Count; i++) RelayServerCdkeyStoreInfo store = new RelayServerCdkeyStoreInfo
{ {
RelayServerCdkeyStoreInfo store = new RelayServerCdkeyStoreInfo UseTime = DateTime.Now,
{ AddTime = DateTime.Now,
UseTime = DateTime.Now, Bandwidth = order.Speed,
AddTime = DateTime.Now, CostPrice = order.CostPrice,
Bandwidth = order.Speed, EndTime = DateTime.Now
CostPrice = order.CostPrice, .AddYears(int.Parse(time[1].Value))
EndTime = DateTime.Now .AddMonths(int.Parse(time[2].Value))
.AddYears(int.Parse(time[1].Value)) .AddDays(int.Parse(time[3].Value))
.AddMonths(int.Parse(time[2].Value)) .AddHours(int.Parse(time[4].Value))
.AddDays(int.Parse(time[3].Value)) .AddMinutes(int.Parse(time[5].Value))
.AddHours(int.Parse(time[4].Value)) .AddSeconds(int.Parse(time[6].Value)),
.AddMinutes(int.Parse(time[5].Value)) LastBytes = order.Speed * 1024 * 1024 * 1024 * order.Count,
.AddSeconds(int.Parse(time[6].Value)), MaxBytes = order.Speed * 1024 * 1024 * 1024 * order.Count,
LastBytes = order.Speed * 1024 * 1024 * 1024, Price = order.Price,
MaxBytes = order.Speed * 1024 * 1024 * 1024, Remark = "order",
Price = order.Price, StartTime = DateTime.Now,
Remark = "order", UserId = order.WidgetUserId,
StartTime = DateTime.Now, CdkeyId = YitIdHelper.NextId(),
UserId = order.WidgetUserId, Contact = order.Contact,
CdkeyId = YitIdHelper.NextId(), OrderId = order.OrderId,
Contact = order.Contact, PayPrice = order.PayPrice,
OrderId = order.OrderId, UserPrice = order.UserPrice,
PayPrice = order.PayPrice, Id = ObjectId.NewObjectId().ToString()
UserPrice = order.UserPrice, };
Id = ObjectId.NewObjectId().ToString() liteCollection.Insert(store);
};
liteCollection.Insert(store);
}
return await Task.FromResult(true); return await Task.FromResult(true);
} }

View File

@@ -22,6 +22,17 @@ namespace linker.messenger.store.file.relay
{ {
config.Data.Server.Relay.Distributed.Node = node; config.Data.Server.Relay.Distributed.Node = node;
} }
public void UpdateInfo(RelayServerNodeUpdateInfo update)
{
config.Data.Server.Relay.Distributed.Node.Name = update.Name;
config.Data.Server.Relay.Distributed.Node.MaxConnection = update.MaxConnection;
config.Data.Server.Relay.Distributed.Node.MaxBandwidth = update.MaxBandwidth;
config.Data.Server.Relay.Distributed.Node.MaxBandwidthTotal = update.MaxBandwidthTotal;
config.Data.Server.Relay.Distributed.Node.MaxGbTotal = update.MaxGbTotal;
config.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes = update.MaxGbTotalLastBytes;
config.Data.Server.Relay.Distributed.Node.Public = update.Public;
}
public void SetMaxGbTotalLastBytes(long value) public void SetMaxGbTotalLastBytes(long value)
{ {
config.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes=value; config.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes=value;

View File

@@ -23,4 +23,7 @@ export const relayCdkeyDel = (data) => {
} }
export const relayCdkeyMy = (data) => { export const relayCdkeyMy = (data) => {
return sendWebsocketMsg('relay/MyCdkey', data); return sendWebsocketMsg('relay/MyCdkey', data);
}
export const relayCdkeyTest = (data) => {
return sendWebsocketMsg('relay/TestCdkey', data);
} }

View File

@@ -141,7 +141,7 @@ export default {
'server.relayCdkeyPayPrice': 'Pay price', 'server.relayCdkeyPayPrice': 'Pay price',
'server.relayCdkeyCostPrice': 'Cost price', 'server.relayCdkeyCostPrice': 'Cost price',
'server.relayCdkeyUserPrice': 'User price', 'server.relayCdkeyUserPrice': 'User price',
'server.relayCdkeyOrderId': 'Order No', 'server.relayCdkeyOrderId': 'OrderNo',
'server.relayCdkeyContact': 'Email', 'server.relayCdkeyContact': 'Email',
'server.relayCdkeyRemark': 'Remark', 'server.relayCdkeyRemark': 'Remark',
@@ -161,6 +161,14 @@ export default {
'server.relayCdkeyOper': 'Oper', 'server.relayCdkeyOper': 'Oper',
'server.relayCdkeyDelConfirm': 'Are you sure to delete', 'server.relayCdkeyDelConfirm': 'Are you sure to delete',
'server.relayCdkeyFlagAll': 'All',
'server.relayCdkeyFlagTimein': 'In end time',
'server.relayCdkeyFlagTimeout': 'Out end time',
'server.relayCdkeyFlagBytesin': 'Has bytes',
'server.relayCdkeyFlagBytesout': 'Not have bytes',
'server.relayCdkeyFlagDeleted': 'Deleted',
'server.relayCdkeyFlagUnDeleted': 'Not deleted',
'server.sforwardSecretKey': 'Server forward secretKey', 'server.sforwardSecretKey': 'Server forward secretKey',
'server.sforwardText': 'The server forward can be used when the key is correct', 'server.sforwardText': 'The server forward can be used when the key is correct',

View File

@@ -164,6 +164,35 @@ export default {
'server.relayCdkeyOper': '操作', 'server.relayCdkeyOper': '操作',
'server.relayCdkeyDelConfirm': '确认删除吗?', 'server.relayCdkeyDelConfirm': '确认删除吗?',
'server.relayCdkeyFlagAll': '全部',
'server.relayCdkeyFlagTimein': '有效期内',
'server.relayCdkeyFlagTimeout': '有效期外',
'server.relayCdkeyFlagBytesin': '剩余',
'server.relayCdkeyFlagBytesout': '已用完',
'server.relayCdkeyFlagDeleted': '已删除',
'server.relayCdkeyFlagUnDeleted': '未删除',
'server.relayCdkeyTestTitle': '测试解密CDKEY',
'server.relayCdkeyTestKey': 'CDKEY',
'server.relayCdkeyTestGB': '流量',
'server.relayCdkeyTestGBError': '流量要大于0',
'server.relayCdkeyTestSpeed': '带宽Mbps',
'server.relayCdkeyTestSpeedError': '带宽要大于0',
'server.relayCdkeyTestTime': '持续时间',
'server.relayCdkeyTestTimeError': '格式错误',
'server.relayCdkeyTestUserId': '用户标识',
'server.relayCdkeyTestUserIdError': '用户标识不正确',
'server.relayCdkeyTestOrderId': '订单',
'server.relayCdkeyTestOrderIdError': '订单号不能为空',
'server.relayCdkeyTestContact': '联系方式',
'server.relayCdkeyTestCostPrice': '成本',
'server.relayCdkeyTestPrice': '原价',
'server.relayCdkeyTestUserPrice': '会员价',
'server.relayCdkeyTestPayPrice': '支付',
'server.relayCdkeyTestCount': '数量',
'server.relayCdkeyTestCountError': '数量要大于0',
'server.relayCdkeyTestParseError': '解密失败',
'server.sforwardSecretKey': '服务器穿透密钥', 'server.sforwardSecretKey': '服务器穿透密钥',
'server.sforwardText': '当密钥正确是可用', 'server.sforwardText': '当密钥正确是可用',

View File

@@ -31,20 +31,19 @@
<span v-else>{{ scope.row.MaxBandwidth }}Mbps</span> <span v-else>{{ scope.row.MaxBandwidth }}Mbps</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column property="MaxBandwidthTotal" :label="$t('server.relaySpeed1')" width="80"> <el-table-column property="MaxBandwidthTotal" :label="`${$t('server.relaySpeed2')}/${$t('server.relaySpeed1')}`" width="120">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.MaxBandwidthTotal == 0">--</span> <span>
<span v-else>{{ scope.row.MaxBandwidthTotal }}Mbps</span> <span>{{scope.row.BandwidthRatio}}Mbps</span>
<span>/</span>
<span v-if="scope.row.MaxBandwidthTotal == 0">--</span>
<span v-else>{{ scope.row.MaxBandwidthTotal }}Mbps</span>
</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column property="BandwidthRatio" :label="$t('server.relaySpeed2')" width="66"> <el-table-column property="ConnectionRatio" :label="$t('server.relayConnection')" width="100">
<template #default="scope"> <template #default="scope">
<span>{{ (scope.row.BandwidthRatio*100).toFixed(2) }}%</span> <span><strong>{{scope.row.ConnectionRatio}}</strong>/{{scope.row.MaxConnection}}</span>
</template>
</el-table-column>
<el-table-column property="ConnectionRatio" :label="$t('server.relayConnection')" width="60">
<template #default="scope">
<span>{{ (scope.row.ConnectionRatio*100).toFixed(2) }}%</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column property="Delay" :label="$t('server.relayDelay')" width="60"> <el-table-column property="Delay" :label="$t('server.relayDelay')" width="60">

View File

@@ -0,0 +1,139 @@
<template>
<el-dialog class="options-center" :title="$t('server.relayAddCdkey')" destroy-on-close v-model="state.show" width="60rem" top="2vh">
<div>
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
<el-form-item :label="$t('server.relayCdkeyUserId')" prop="UserId">
<el-input maxlength="32" show-word-limit v-model="state.ruleForm.UserId" />
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyBandwidth')" prop="Bandwidth">
<el-input-number size="small" v-model="state.ruleForm.Bandwidth" :min="1" :max="102400" />Mbps
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyBytes')" prop="MaxBytes">
<el-input-number size="small" v-model="state.ruleForm.G" :min="0" :max="102400" />GB
<el-input-number size="small" v-model="state.ruleForm.M" :min="0" :max="1024" />MB
<el-input-number size="small" v-model="state.ruleForm.K" :min="0" :max="1024" />KB
<el-input-number size="small" v-model="state.ruleForm.B" :min="0" :max="1024" />B
</el-form-item>
<el-form-item></el-form-item>
<el-form-item :label="$t('server.relayCdkeyDuration')" prop="EndTime">
<p>
<el-input-number size="small" v-model="state.ruleForm.Year" :min="0" />{{$t('server.relayCdkeyYear')}}
<el-input-number size="small" v-model="state.ruleForm.Month" :min="0" />{{$t('server.relayCdkeyMonth')}}
<el-input-number size="small" v-model="state.ruleForm.Day" :min="0" />{{$t('server.relayCdkeyDay')}}
</p>
<p>
<el-input-number size="small" v-model="state.ruleForm.Hour" :min="0" />{{$t('server.relayCdkeyHour')}}
<el-input-number size="small" v-model="state.ruleForm.Min" :min="0" />{{$t('server.relayCdkeyMin')}}
<el-input-number size="small" v-model="state.ruleForm.Sec" :min="0" />{{$t('server.relayCdkeySec')}}
</p>
</el-form-item>
<el-form-item></el-form-item>
<el-form-item :label="$t('server.relayCdkeyCostPrice')" prop="CostPrice">
<el-input-number size="small" v-model="state.ruleForm.CostPrice" :min="0" />
{{ $t('server.relayCdkeyPrice') }}
<el-input-number size="small" v-model="state.ruleForm.Price" :min="0" />
{{ $t('server.relayCdkeyUserPrice') }}
<el-input-number size="small" v-model="state.ruleForm.UserPrice" :min="0" />
{{ $t('server.relayCdkeyPayPrice') }}
<el-input-number size="small" v-model="state.ruleForm.PayPrice" :min="0" />
</el-form-item>
<el-form-item label="">
<el-row>
<el-col :span="12">
<el-form-item :label="$t('server.relayCdkeyRemark')" prop="Remark">
<el-input v-model="state.ruleForm.Remark" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('server.relayCdkeyContact')" prop="Contact">
<el-input v-model="state.ruleForm.Contact" />
</el-form-item>
</el-col>
</el-row>
</el-form-item>
<el-form-item></el-form-item>
<el-form-item label="" prop="Btns">
<div class="t-c w-100">
<el-button @click="state.show = false">{{$t('common.cancel')}}</el-button>
<el-button type="primary" @click="handleSave">{{$t('common.confirm')}}</el-button>
</div>
</el-form-item>
</el-form>
</div>
</el-dialog>
</template>
<script>
import { ElMessage } from 'element-plus';
import { reactive, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n';
import moment from "moment";
import { relayCdkeyAdd } from '@/apis/relay';
export default {
props: ['modelValue'],
emits: ['update:modelValue','success'],
setup(props,{emit}) {
const {t} = useI18n();
const state = reactive({
show:true,
ruleForm:{
UserId:'',
Bandwidth:1,
G:1,
M:0,
K:0,
B:0,
Year:1,
Month:0,
Day:0,
Hour:0,
Min:0,
Sec:0,
CostPrice:0,
Price:0,
UserPrice:0,
PayPrice:0,
Remark:'hand',
Contact:'',
},
rules:{
UserId: [{ required: true, message: "required", trigger: "blur" }],
Remark: [{ required: true, message: "required", trigger: "blur" }],
}
});
watch(() => state.show, (val) => {
if (!val) {
setTimeout(() => {
emit('update:modelValue', val);
}, 300);
}
});
const ruleFormRef = ref(null);
const handleSave = ()=>{
ruleFormRef.value.validate((valid) => {
if (!valid) return;
const json = JSON.parse(JSON.stringify(state.ruleForm));
const date = new Date();
const end = new Date(date.getFullYear()+json.Year,date.getMonth()+json.Month,date.getDate()+json.Day,date.getHours()+json.Hour,date.getMinutes()+json.Min,date.getSeconds()+json.Sec);
json.EndTime = moment(end).format("YYYY-MM-DD HH:mm:ss");
json.MaxBytes = json.G*1024*1024*1024 + json.M*1024*1024 + json.K*1024 + json.B;
relayCdkeyAdd(json).then(()=>{
ElMessage.success(t('common.oper'));
state.show = false;
emit('success');
}).catch(()=>{
ElMessage.error(t('common.operFail'));
});
});
}
return {state,ruleFormRef,handleSave}
}
}
</script>
<style lang="stylus" scoped>
.el-form-item{margin-bottom:1rem}
.el-input-number--small{width:10rem !important}
</style>

View File

@@ -0,0 +1,50 @@
<template>
<div class="wrap">
<el-radio-group v-model="state.time" size="small" @change="handleChange">
<el-radio-button :label="$t('server.relayCdkeyFlagAll')" :value="0" />
<el-radio-button :label="$t('server.relayCdkeyFlagTimein')" :value="1" />
<el-radio-button :label="$t('server.relayCdkeyFlagTimeout')" :value="2"/>
</el-radio-group>
<el-radio-group v-model="state.bytes" size="small" @change="handleChange">
<el-radio-button :label="$t('server.relayCdkeyFlagAll')" :value="0" />
<el-radio-button :label="$t('server.relayCdkeyFlagBytesin')" :value="4" />
<el-radio-button :label="$t('server.relayCdkeyFlagBytesout')" :value="8"/>
</el-radio-group>
<el-radio-group v-model="state.deleted" size="small" @change="handleChange">
<el-radio-button :label="$t('server.relayCdkeyFlagAll')" :value="0" />
<el-radio-button :label="$t('server.relayCdkeyFlagUnDeleted')" :value="16" />
<el-radio-button :label="$t('server.relayCdkeyFlagDeleted')" :value="32"/>
</el-radio-group>
</div>
</template>
<script>
import { onMounted, reactive } from 'vue';
export default {
emits:['change'],
setup (props,{emit}) {
const state = reactive({
time: 1,
bytes: 4,
deleted: 16,
});
const handleChange = () => {
emit('change',state.time | state.bytes | state.deleted);
}
onMounted(() => {
handleChange();
})
return {state,handleChange}
}
}
</script>
<style lang="stylus" scoped>
.el-radio-group{margin-right:.6rem}
.wrap{padding-bottom:1rem}
</style>

View File

@@ -20,7 +20,7 @@ export default {
const state = reactive({ const state = reactive({
hasRelayCdkey:false, hasRelayCdkey:false,
showManager:false, showManager:false,
showMy:false showMy:true
}); });
onMounted(()=>{ onMounted(()=>{

View File

@@ -1,21 +1,29 @@
<template> <template>
<el-dialog class="options-center" :title="$t('server.relayCdkey')" destroy-on-close v-model="state.show" width="77rem" top="2vh"> <el-dialog class="options-center" :title="$t('server.relayCdkey')" destroy-on-close v-model="state.show" width="77rem" top="2vh">
<div class="group-wrap"> <div class="group-wrap">
<div class="head flex"> <div class="head">
<div><span>{{$t('server.relayCdkeyUserId')}}</span> <el-input v-model="state.page.UserId" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div class="search flex">
<div><span>{{$t('server.relayCdkeyOrderId')}}</span> <el-input v-model="state.page.OrderId" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.relayCdkeyUserId')}}</span> <el-input v-model="state.page.UserId" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<div><span>{{$t('server.relayCdkeyContact')}}</span> <el-input v-model="state.page.Contact" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.relayCdkeyOrderId')}}</span> <el-input v-model="state.page.OrderId" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<div><span>{{$t('server.relayCdkeyRemark')}}</span> <el-input v-model="state.page.Remark" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.relayCdkeyContact')}}</span> <el-input v-model="state.page.Contact" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<div> <div><span>{{$t('server.relayCdkeyRemark')}}</span> <el-input v-model="state.page.Remark" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<el-button size="small" @click="handleSearch()"> <div>
<el-icon><Search /></el-icon> <el-button size="small" @click="handleSearch()">
</el-button> <el-icon><Search /></el-icon>
</div> </el-button>
<div> </div>
<el-button size="small" type="success" @click="handleAdd()"> <div>
<el-icon><Plus /></el-icon> <el-button size="small" @click="state.showTest = true">
</el-button> <el-icon><Warning /></el-icon>
</el-button>
</div>
<div>
<el-button size="small" type="success" @click="state.showAdd = true">
<el-icon><Plus /></el-icon>
</el-button>
</div>
</div> </div>
<Flags @change="handleFlagsChange"></Flags>
</div> </div>
<el-table stripe :data="state.list.List" border size="small" width="100%" @sort-change="handleSort"> <el-table stripe :data="state.list.List" border size="small" width="100%" @sort-change="handleSort">
<el-table-column prop="Bandwidth" :label="$t('server.relayCdkeyBandwidth')" width="110" sortable="custom"> <el-table-column prop="Bandwidth" :label="$t('server.relayCdkeyBandwidth')" width="110" sortable="custom">
@@ -39,8 +47,7 @@
<p>{{ scope.row.Contact }}</p> <p>{{ scope.row.Contact }}</p>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="Remark" :label="$t('server.relayCdkeyRemark')"> <el-table-column prop="Remark" :label="$t('server.relayCdkeyRemark')"></el-table-column>
</el-table-column>
<el-table-column prop="EndTime" :label="`${$t('server.relayCdkeyEndTime')}`" width="140" sortable="custom"> <el-table-column prop="EndTime" :label="`${$t('server.relayCdkeyEndTime')}`" width="140" sortable="custom">
</el-table-column> </el-table-column>
<el-table-column prop="UseTime" :label="`${$t('server.relayCdkeyUseTime')}`" width="140" sortable="custom"> <el-table-column prop="UseTime" :label="`${$t('server.relayCdkeyUseTime')}`" width="140" sortable="custom">
@@ -72,105 +79,26 @@
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog class="options-center" :title="$t('server.relayAddCdkey')" destroy-on-close v-model="state.showAdd" width="60rem" top="2vh"> <Add v-if="state.showAdd" v-model="state.showAdd" @success="handleSearch"></Add>
<div> <Test v-if="state.showTest" v-model="state.showTest"></Test>
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
<el-form-item :label="$t('server.relayCdkeyUserId')" prop="UserId">
<el-input maxlength="32" show-word-limit v-model="state.ruleForm.UserId" />
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyBandwidth')" prop="Bandwidth">
<el-input-number size="small" v-model="state.ruleForm.Bandwidth" :min="1" :max="102400" />Mbps
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyBytes')" prop="MaxBytes">
<el-input-number size="small" v-model="state.ruleForm.G" :min="0" :max="102400" />GB
<el-input-number size="small" v-model="state.ruleForm.M" :min="0" :max="1024" />MB
<el-input-number size="small" v-model="state.ruleForm.K" :min="0" :max="1024" />KB
<el-input-number size="small" v-model="state.ruleForm.B" :min="0" :max="1024" />B
</el-form-item>
<el-form-item></el-form-item>
<el-form-item :label="$t('server.relayCdkeyDuration')" prop="EndTime">
<p>
<el-input-number size="small" v-model="state.ruleForm.Year" :min="0" />{{$t('server.relayCdkeyYear')}}
<el-input-number size="small" v-model="state.ruleForm.Month" :min="0" />{{$t('server.relayCdkeyMonth')}}
<el-input-number size="small" v-model="state.ruleForm.Day" :min="0" />{{$t('server.relayCdkeyDay')}}
</p>
<p>
<el-input-number size="small" v-model="state.ruleForm.Hour" :min="0" />{{$t('server.relayCdkeyHour')}}
<el-input-number size="small" v-model="state.ruleForm.Min" :min="0" />{{$t('server.relayCdkeyMin')}}
<el-input-number size="small" v-model="state.ruleForm.Sec" :min="0" />{{$t('server.relayCdkeySec')}}
</p>
</el-form-item>
<el-form-item></el-form-item>
<el-form-item :label="$t('server.relayCdkeyCostPrice')" prop="CostPrice">
<el-input-number size="small" v-model="state.ruleForm.CostPrice" :min="0" />
{{ $t('server.relayCdkeyPrice') }}
<el-input-number size="small" v-model="state.ruleForm.Price" :min="0" />
{{ $t('server.relayCdkeyUserPrice') }}
<el-input-number size="small" v-model="state.ruleForm.UserPrice" :min="0" />
{{ $t('server.relayCdkeyPayPrice') }}
<el-input-number size="small" v-model="state.ruleForm.PayPrice" :min="0" />
</el-form-item>
<el-form-item label="">
<el-row>
<el-col :span="12">
<el-form-item :label="$t('server.relayCdkeyRemark')" prop="Remark">
<el-input v-model="state.ruleForm.Remark" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('server.relayCdkeyContact')" prop="Contact">
<el-input v-model="state.ruleForm.Contact" />
</el-form-item>
</el-col>
</el-row>
</el-form-item>
<el-form-item></el-form-item>
<el-form-item label="" prop="Btns">
<div class="t-c w-100">
<el-button @click="state.showAdd = false">取消</el-button>
<el-button type="primary" @click="handleSave">确认</el-button>
</div>
</el-form-item>
</el-form>
</div>
</el-dialog>
</template> </template>
<script> <script>
import { injectGlobalData } from '@/provide'; import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { onMounted, reactive, watch } from 'vue'
import { onMounted, reactive, ref, watch } from 'vue' import { Delete,Plus,Search,Warning } from '@element-plus/icons-vue';
import { Delete,Plus,Search } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import moment from "moment"; import { relayCdkeyDel,relayCdkeyPage } from '@/apis/relay';
import { relayCdkeyAdd,relayCdkeyDel,relayCdkeyPage } from '@/apis/relay'; import Flags from './Flags.vue';
import Add from './Add.vue';
import Test from './Test.vue';
export default { export default {
props: ['modelValue'], props: ['modelValue'],
emits: ['update:modelValue'], emits: ['update:modelValue'],
components:{Delete,Plus,Search }, components:{Delete,Plus,Search ,Flags,Add,Test,Warning},
setup(props,{emit}) { setup(props,{emit}) {
const {t} = useI18n(); const {t} = useI18n();
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const defaultJson = {
UserId:'',
Bandwidth:1,
G:1,
M:0,
K:0,
B:0,
Year:1,
Month:0,
Day:0,
Hour:0,
Min:0,
Sec:0,
CostPrice:0,
Price:0,
UserPrice:0,
PayPrice:0,
Remark:'hand',
Contact:'',
};
const state = reactive({ const state = reactive({
page:{ page:{
Page:1, Page:1,
@@ -181,6 +109,7 @@ export default {
OrderId:'', OrderId:'',
Contact:'', Contact:'',
Remark:'', Remark:'',
Flag:0
}, },
list:{ list:{
Page:1, Page:1,
@@ -190,11 +119,7 @@ export default {
}, },
show:true, show:true,
showAdd:false, showAdd:false,
ruleForm:JSON.parse(JSON.stringify(defaultJson)), showTest:false
rules:{
UserId: [{ required: true, message: "required", trigger: "blur" }],
Remark: [{ required: true, message: "required", trigger: "blur" }],
}
}); });
watch(() => state.show, (val) => { watch(() => state.show, (val) => {
if (!val) { if (!val) {
@@ -212,6 +137,10 @@ export default {
return `${(num*1.0).toFixed(2)}${['B', 'KB', 'MB', 'GB', 'TB'][index]}`; return `${(num*1.0).toFixed(2)}${['B', 'KB', 'MB', 'GB', 'TB'][index]}`;
} }
const handleFlagsChange = (flag)=>{
state.page.Flag = flag;
handleSearch();
}
const handleSearch = ()=>{ const handleSearch = ()=>{
relayCdkeyPage(state.page).then((res)=>{ relayCdkeyPage(state.page).then((res)=>{
state.list = res; state.list = res;
@@ -227,50 +156,26 @@ export default {
handleSearch(); handleSearch();
} }
const handleAdd = (row)=>{
state.ruleForm = JSON.parse(JSON.stringify(defaultJson));
state.showAdd = true;
}
const handleDel = (row)=>{ const handleDel = (row)=>{
relayCdkeyDel(row.CdkeyId).then((res)=>{ relayCdkeyDel(row.CdkeyId).then((res)=>{
handleSearch(); handleSearch();
}).catch(()=>{}) }).catch(()=>{})
} }
const ruleFormRef = ref(null);
const handleSave = ()=>{
ruleFormRef.value.validate((valid) => {
if (!valid) return;
const json = JSON.parse(JSON.stringify(state.ruleForm));
const date = new Date();
const end = new Date(date.getFullYear()+json.Year,date.getMonth()+json.Month,date.getDate()+json.Day,date.getHours()+json.Hour,date.getMinutes()+json.Min,date.getSeconds()+json.Sec);
json.EndTime = moment(end).format("YYYY-MM-DD HH:mm:ss");
json.MaxBytes = json.G*1024*1024*1024 + json.M*1024*1024 + json.K*1024 + json.B;
relayCdkeyAdd(json).then(()=>{
ElMessage.success(t('common.oper'));
state.showAdd = false;
handleSearch();
}).catch(()=>{
ElMessage.error(t('common.operFail'));
});
});
}
onMounted(()=>{ onMounted(()=>{
handleSearch(); handleSearch();
}) })
return {state,ruleFormRef,parseSpeed,handleSort,handleSearch,handlePageChange,handleAdd,handleDel,handleSave} return {state,parseSpeed,handleSort,handleFlagsChange,handleSearch,handlePageChange,handleDel}
} }
} }
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.head{ .head{
&>div{ .search{
margin-right:1rem; &>div{
margin-right:1rem;
}
} }
} }
.page{ .page{

View File

@@ -1,15 +1,18 @@
<template> <template>
<el-dialog class="options-center" :title="$t('server.relayMyCdkey')" destroy-on-close v-model="state.show" width="77rem" top="2vh"> <el-dialog class="options-center" :title="$t('server.relayMyCdkey')" destroy-on-close v-model="state.show" width="77rem" top="2vh">
<div class="group-wrap"> <div class="group-wrap">
<div class="head flex"> <div class="head">
<div><span>{{$t('server.relayCdkeyOrderId')}}</span> <el-input v-model="state.page.OrderId" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div class="search flex">
<div><span>{{$t('server.relayCdkeyContact')}}</span> <el-input v-model="state.page.Contact" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.relayCdkeyOrderId')}}</span> <el-input v-model="state.page.OrderId" style="width:10rem" size="small" clearable @change="handleSearch" /></div>
<div><span>{{$t('server.relayCdkeyRemark')}}</span> <el-input v-model="state.page.Remark" style="width:10rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.relayCdkeyContact')}}</span> <el-input v-model="state.page.Contact" style="width:10rem" size="small" clearable @change="handleSearch" /></div>
<div> <div><span>{{$t('server.relayCdkeyRemark')}}</span> <el-input v-model="state.page.Remark" style="width:10rem" size="small" clearable @change="handleSearch" /></div>
<el-button size="small" @click="handleSearch()"> <div>
<el-icon><Search /></el-icon> <el-button size="small" @click="handleSearch()">
</el-button> <el-icon><Search /></el-icon>
</el-button>
</div>
</div> </div>
<Flags @change="handleFlagsChange"></Flags>
</div> </div>
<el-table stripe :data="state.list.List" border size="small" width="100%" @sort-change="handleSort"> <el-table stripe :data="state.list.List" border size="small" width="100%" @sort-change="handleSort">
<el-table-column prop="Bandwidth" :label="$t('server.relayCdkeyBandwidth')" width="110" sortable="custom"> <el-table-column prop="Bandwidth" :label="$t('server.relayCdkeyBandwidth')" width="110" sortable="custom">
@@ -75,10 +78,11 @@ import { onMounted, reactive, watch } from 'vue'
import { Delete,Plus,Search } from '@element-plus/icons-vue'; import { Delete,Plus,Search } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import {relayCdkeyMy,relayCdkeyDel } from '@/apis/relay'; import {relayCdkeyMy,relayCdkeyDel } from '@/apis/relay';
import Flags from './Flags.vue';
export default { export default {
props: ['modelValue'], props: ['modelValue'],
emits: ['update:modelValue'], emits: ['update:modelValue'],
components:{Delete,Plus,Search }, components:{Delete,Plus,Search,Flags },
setup(props,{emit}) { setup(props,{emit}) {
const {t} = useI18n(); const {t} = useI18n();
const globalData = injectGlobalData(); const globalData = injectGlobalData();
@@ -91,6 +95,7 @@ export default {
OrderId:'', OrderId:'',
Contact:'', Contact:'',
Remark:'', Remark:'',
Flag:0
}, },
list:{ list:{
Page:1, Page:1,
@@ -116,6 +121,10 @@ export default {
return `${(num*1.0).toFixed(2)}${['B', 'KB', 'MB', 'GB', 'TB'][index]}`; return `${(num*1.0).toFixed(2)}${['B', 'KB', 'MB', 'GB', 'TB'][index]}`;
} }
const handleFlagsChange = (flag)=>{
state.page.Flag = flag;
handleSearch();
}
const handleSearch = ()=>{ const handleSearch = ()=>{
relayCdkeyMy(state.page).then((res)=>{ relayCdkeyMy(state.page).then((res)=>{
state.list = res; state.list = res;
@@ -139,14 +148,16 @@ export default {
handleSearch(); handleSearch();
}) })
return {state,parseSpeed,handleSort,handleSearch,handlePageChange,handleDel} return {state,parseSpeed,handleSort,handleFlagsChange,handleSearch,handlePageChange,handleDel}
} }
} }
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.head{ .head{
&>div{ .search{
margin-right:1rem; &>div{
margin-right:1rem;
}
} }
} }
.page{ .page{

View File

@@ -0,0 +1,189 @@
<template>
<el-dialog class="options-center" :title="$t('server.relayCdkeyTestTitle')" destroy-on-close v-model="state.show" width="40rem" top="2vh">
<div>
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
<el-form-item :label="$t('server.relayCdkeyTestKey')" prop="Base64">
<el-input v-model="state.Base64" @change="handleChange" />
</el-form-item>
<el-form-item label="" v-if="state.ruleForm.Field.indexOf('Parse')>=0">
<div class="t-c w-100">
<span class="red">{{$t('server.relayCdkeyTestParseError')}}</span>
</div>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestGB')" prop="GB">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.GB" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('GB')>=0">{{$t('server.relayCdkeyTestGBError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestSpeed')" prop="Speed">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.Speed" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('Speed')>=0">{{$t('server.relayCdkeyTestSpeedError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestTime')" prop="Time">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.Time" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('Time')>=0">{{$t('server.relayCdkeyTestTimeError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestUserId')" prop="WidgetUserId">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.WidgetUserId" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('UserId')>=0">{{$t('server.relayCdkeyTestUserIdError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestOrderId')" prop="OrderId">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.OrderId" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('OrderId')>=0">{{$t('server.relayCdkeyTestOrderIdError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestContact')" prop="Contact">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.Contact" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('Contact')>=0">{{$t('server.relayCdkeyTestContactError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestCostPrice')" prop="CostPrice">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.CostPrice" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('CostPrice')>=0">{{$t('server.relayCdkeyTestCostPriceError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestPrice')" prop="Price">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.Price" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('Price')>=0">{{$t('server.relayCdkeyTestPriceError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestUserPrice')" prop="UserPrice">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.UserPrice" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('UserPrice')>=0">{{$t('server.relayCdkeyTestUserPriceError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestPayPrice')" prop="PayPrice">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.PayPrice" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('PayPrice')>=0">{{$t('server.relayCdkeyTestPayPriceError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('server.relayCdkeyTestCount')" prop="Count">
<el-row>
<el-col :span="18">
<el-input v-model="state.ruleForm.Order.Count" />
</el-col>
<el-col :span="6">
<span class="red" v-if="state.ruleForm.Field.indexOf('Count')>=0">{{$t('server.relayCdkeyTestCountError')}}</span>
<span v-else class="green">success</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="" prop="Btns">
<div class="t-c w-100">
<el-button @click="state.show = false">{{$t('common.cancel')}}</el-button>
<el-button type="primary" @click="handleChange">{{$t('common.confirm')}}</el-button>
</div>
</el-form-item>
</el-form>
</div>
</el-dialog>
</template>
<script>
import { reactive, watch } from 'vue'
import { Search } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n';
import { relayCdkeyTest } from '@/apis/relay';
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
components:{Search},
setup(props,{emit}) {
const {t} = useI18n();
const state = reactive({
show:true,
Base64:'qn1vYOBtu81DkBI10nTTw7h/Vzi1Do3X1HI2+P5fflINL2wNPxrUYQPeOxUqgT+RcZSKLGF3dCMOyYBB+1VKmuI6ZaN86Whr1Xux2dY25tI5/3i/x/K1S78E6+E70ruh61phQZT3QLLVAHnIa2HpFhtPLKZaWc++ReSzixBqkW/sTT/l2iDqG2rl/zKynRM6srXWJkJr+2Msme1u5/Qu/0o6VaJ3ylv71HlB4zubNybQX5WMsOWrjN4/ruRSVF0LcayshqEfwlpeGR44nn5jMxpgQhxxpk/1flVImF00cC4=',
ruleForm:{
Order:{},
Cdkey:'',
Field:[],
},
rules:{}
});
watch(() => state.show, (val) => {
if (!val) {
setTimeout(() => {
emit('update:modelValue', val);
}, 300);
}
});
const handleChange = ()=>{
relayCdkeyTest({Base64:state.Base64}).then(res=>{
if(res.Cdkey) state.ruleForm.Cdkey = res.Cdkey;
if(res.Field) state.ruleForm.Field = res.Field;
if(res.Order) state.ruleForm.Order = res.Order;
}).catch(()=>{})
}
return {state,handleChange}
}
}
</script>
<style lang="stylus" scoped>
.el-form-item{margin-bottom:1rem}
.el-input-number--small{width:10rem !important}
</style>

View File

@@ -2,6 +2,8 @@
using System.ServiceProcess; using System.ServiceProcess;
using System.Diagnostics; using System.Diagnostics;
using linker.messenger.entry; using linker.messenger.entry;
using linker.tunnel;
using linker.messenger.relay.client;
namespace linker namespace linker
{ {
@@ -56,6 +58,7 @@ namespace linker
LinkerMessengerEntry.Build(); LinkerMessengerEntry.Build();
LinkerMessengerEntry.Setup(ExcludeModule.None); LinkerMessengerEntry.Setup(ExcludeModule.None);
LoggerHelper.Instance.Warning($"current version : {VersionHelper.version}"); LoggerHelper.Instance.Warning($"current version : {VersionHelper.version}");
LoggerHelper.Instance.Warning($"linker env is docker : {Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")}"); LoggerHelper.Instance.Warning($"linker env is docker : {Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")}");
LoggerHelper.Instance.Warning($"linker env os : {System.Runtime.InteropServices.RuntimeInformation.OSDescription}"); LoggerHelper.Instance.Warning($"linker env os : {System.Runtime.InteropServices.RuntimeInformation.OSDescription}");

View File

@@ -1,5 +1,5 @@
v1.6.9 v1.6.9
2025-03-08 01:56:41 2025-03-08 19:25:04
1. 优化linux下路由跟踪问题 1. 优化linux下路由跟踪问题
2. 优化linux下获取本机IP问题 2. 优化linux下获取本机IP问题
3. 增加ICS让win7+、win server2008+支持NAT 3. 增加ICS让win7+、win server2008+支持NAT