228 lines
11 KiB
C#
228 lines
11 KiB
C#
|
|
using System;
|
||
|
|
using System.Text.RegularExpressions;
|
||
|
|
using System.Windows;
|
||
|
|
using System.Windows.Controls;
|
||
|
|
using Newtonsoft.Json.Linq;
|
||
|
|
|
||
|
|
namespace YKC
|
||
|
|
{
|
||
|
|
public partial class GatewayPage : Page
|
||
|
|
{
|
||
|
|
private static readonly Regex IpRegex = new Regex(
|
||
|
|
@"^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$");
|
||
|
|
private static readonly Regex DomainRegex = new Regex(
|
||
|
|
@"^(?!-)[A-Za-z0-9-]{1,63}(?<!-)(\.[A-Za-z]{2,})+$");
|
||
|
|
|
||
|
|
public GatewayPage()
|
||
|
|
{
|
||
|
|
InitializeComponent();
|
||
|
|
Loaded += (s, e) =>
|
||
|
|
{
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
if (txtGwId != null) RefreshAll();
|
||
|
|
}), System.Windows.Threading.DispatcherPriority.Background);
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool IsValidIp(string s) => IpRegex.IsMatch(s);
|
||
|
|
private bool IsValidDomain(string s) => DomainRegex.IsMatch(s);
|
||
|
|
private bool IsValidHost(string s) => IsValidIp(s) || IsValidDomain(s);
|
||
|
|
|
||
|
|
private void ShowResult(TextBlock el, string msg, bool ok)
|
||
|
|
{
|
||
|
|
el.Text = msg;
|
||
|
|
el.Foreground = new System.Windows.Media.SolidColorBrush(
|
||
|
|
(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(
|
||
|
|
ok ? "#10B981" : "#EF4444"));
|
||
|
|
var timer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromSeconds(3) };
|
||
|
|
timer.Tick += (s, _) => { el.Text = ""; timer.Stop(); };
|
||
|
|
timer.Start();
|
||
|
|
}
|
||
|
|
|
||
|
|
private string FormatUptime(int sec)
|
||
|
|
{
|
||
|
|
if (sec <= 0) return "--";
|
||
|
|
int d = sec / 86400;
|
||
|
|
int h = (sec % 86400) / 3600;
|
||
|
|
int m = (sec % 3600) / 60;
|
||
|
|
string result = "";
|
||
|
|
if (d > 0) result += d + "天";
|
||
|
|
if (h > 0) result += h + "时";
|
||
|
|
if (m > 0) result += m + "分";
|
||
|
|
return result.Length > 0 ? result : sec + "秒";
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RefreshAll()
|
||
|
|
{
|
||
|
|
RefreshGwInfo();
|
||
|
|
Refresh4G();
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void RefreshGwInfo()
|
||
|
|
{
|
||
|
|
txtGwStatus.Text = "加载中...";
|
||
|
|
txtGwStatus.Foreground = new System.Windows.Media.SolidColorBrush(
|
||
|
|
(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#64748B"));
|
||
|
|
await System.Threading.Tasks.Task.Run(() =>
|
||
|
|
{
|
||
|
|
var result = UdpClientHolder.Instance.SendSync(new JObject { ["cmd"] = Config.Cmd["GET_GW_INFO"] });
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
if (result.Value<bool>("success") && result["device_id"] != null)
|
||
|
|
{
|
||
|
|
txtGwId.Text = result.Value<string>("device_id") ?? "--";
|
||
|
|
txtGwSw.Text = result.Value<string>("software_ver") ?? result.Value<string>("sw_ver") ?? "--";
|
||
|
|
txtGwHw.Text = result.Value<string>("hardware_ver") ?? result.Value<string>("hw_ver") ?? "--";
|
||
|
|
txtGwUptime.Text = FormatUptime(result.Value<int?>("uptime") ?? 0);
|
||
|
|
txtGwStatus.Text = "";
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
txtGwId.Text = "--"; txtGwSw.Text = "--"; txtGwHw.Text = "--"; txtGwUptime.Text = "--";
|
||
|
|
ShowResult(txtGwStatus, result.Value<string>("error") ?? "查询超时", false);
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void Refresh4G()
|
||
|
|
{
|
||
|
|
txt4GStatus.Text = "加载中...";
|
||
|
|
txt4GStatus.Foreground = new System.Windows.Media.SolidColorBrush(
|
||
|
|
(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#64748B"));
|
||
|
|
await System.Threading.Tasks.Task.Run(() =>
|
||
|
|
{
|
||
|
|
var result = UdpClientHolder.Instance.SendSync(new JObject { ["cmd"] = Config.Cmd["GET_4G_STATUS"] });
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
if (result.Value<bool>("success") && result["sim"] != null)
|
||
|
|
{
|
||
|
|
txtSim.Text = result.Value<string>("sim") ?? result.Value<string>("iccid") ?? "--";
|
||
|
|
txtNetStatus.Text = result.Value<string>("net_status") ?? result.Value<string>("status_text") ?? "--";
|
||
|
|
txtSignal.Text = result.Value<string>("signal") != null ? result.Value<int>("signal") + " dBm" : "--";
|
||
|
|
txtIsp.Text = result.Value<string>("isp") ?? result.Value<string>("operator") ?? "--";
|
||
|
|
txt4GStatus.Text = "";
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
txtSim.Text = "--"; txtNetStatus.Text = "--"; txtSignal.Text = "--"; txtIsp.Text = "--";
|
||
|
|
ShowResult(txt4GStatus, result.Value<string>("error") ?? "查询超时", false);
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RefreshGwInfo_Click(object sender, RoutedEventArgs e) => RefreshGwInfo();
|
||
|
|
private void Refresh4G_Click(object sender, RoutedEventArgs e) => Refresh4G();
|
||
|
|
|
||
|
|
private async void LoadCloudConfig_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
txtCloudResult.Text = "加载中...";
|
||
|
|
txtCloudResult.Foreground = new System.Windows.Media.SolidColorBrush(
|
||
|
|
(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#64748B"));
|
||
|
|
await System.Threading.Tasks.Task.Run(() =>
|
||
|
|
{
|
||
|
|
var result = UdpClientHolder.Instance.SendSync(new JObject { ["cmd"] = Config.Cmd["GET_CLOUD_CONFIG"] });
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
txtCloudResult.Text = "";
|
||
|
|
if (result.Value<bool>("success") && result["host"] != null)
|
||
|
|
{
|
||
|
|
txtCloudHost.Text = result.Value<string>("host") ?? "";
|
||
|
|
txtCloudPort.Text = result.Value<string>("port") ?? result.Value<int?>("port")?.ToString() ?? "";
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ShowResult(txtCloudResult, result.Value<string>("error") ?? "查询超时", false);
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void SaveCloudConfig_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
string host = txtCloudHost.Text.Trim();
|
||
|
|
string port = txtCloudPort.Text.Trim();
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(host)) { ShowResult(txtCloudResult, "请输入服务器地址", false); return; }
|
||
|
|
if (!IsValidHost(host)) { ShowResult(txtCloudResult, "地址格式错误", false); return; }
|
||
|
|
if (string.IsNullOrEmpty(port) || !int.TryParse(port, out int p) || p < 1 || p > 65535)
|
||
|
|
{ ShowResult(txtCloudResult, "端口范围 1-65535", false); return; }
|
||
|
|
|
||
|
|
ShowResult(txtCloudResult, "保存中...", true);
|
||
|
|
await System.Threading.Tasks.Task.Run(() =>
|
||
|
|
{
|
||
|
|
var result = UdpClientHolder.Instance.SendSync(new JObject
|
||
|
|
{
|
||
|
|
["cmd"] = Config.Cmd["SET_CLOUD_CONFIG"],
|
||
|
|
["host"] = host,
|
||
|
|
["port"] = p
|
||
|
|
});
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
ShowResult(txtCloudResult, result.Value<bool>("success") ? "保存成功" : (result.Value<string>("error") ?? "失败"), result.Value<bool>("success"));
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void LoadNetConfig_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
txtNetResult.Text = "加载中...";
|
||
|
|
txtNetResult.Foreground = new System.Windows.Media.SolidColorBrush(
|
||
|
|
(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#64748B"));
|
||
|
|
await System.Threading.Tasks.Task.Run(() =>
|
||
|
|
{
|
||
|
|
var result = UdpClientHolder.Instance.SendSync(new JObject { ["cmd"] = Config.Cmd["GET_NET_CONFIG"] });
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
txtNetResult.Text = "";
|
||
|
|
if (result.Value<bool>("success") && result["ip"] != null)
|
||
|
|
{
|
||
|
|
txtNetIp.Text = result.Value<string>("ip") ?? "";
|
||
|
|
txtNetMask.Text = result.Value<string>("mask") ?? result.Value<string>("netmask") ?? "";
|
||
|
|
txtNetGw.Text = result.Value<string>("gateway") ?? result.Value<string>("gw") ?? "";
|
||
|
|
txtNetDns.Text = result.Value<string>("dns") ?? "";
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ShowResult(txtNetResult, result.Value<string>("error") ?? "查询超时", false);
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void SaveNetConfig_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
string ip = txtNetIp.Text.Trim();
|
||
|
|
string mask = txtNetMask.Text.Trim();
|
||
|
|
string gw = txtNetGw.Text.Trim();
|
||
|
|
string dns = txtNetDns.Text.Trim();
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(ip)) { ShowResult(txtNetResult, "请输入IP地址", false); return; }
|
||
|
|
if (!IsValidIp(ip)) { ShowResult(txtNetResult, "IP格式错误", false); return; }
|
||
|
|
if (string.IsNullOrEmpty(mask)) { ShowResult(txtNetResult, "请输入子网掩码", false); return; }
|
||
|
|
if (!IsValidIp(mask)) { ShowResult(txtNetResult, "掩码格式错误", false); return; }
|
||
|
|
if (!string.IsNullOrEmpty(gw) && !IsValidIp(gw)) { ShowResult(txtNetResult, "网关格式错误", false); return; }
|
||
|
|
if (!string.IsNullOrEmpty(dns) && !IsValidIp(dns)) { ShowResult(txtNetResult, "DNS格式错误", false); return; }
|
||
|
|
|
||
|
|
ShowResult(txtNetResult, "保存中...", true);
|
||
|
|
await System.Threading.Tasks.Task.Run(() =>
|
||
|
|
{
|
||
|
|
var result = UdpClientHolder.Instance.SendSync(new JObject
|
||
|
|
{
|
||
|
|
["cmd"] = Config.Cmd["SET_NET_CONFIG"],
|
||
|
|
["ip"] = ip,
|
||
|
|
["mask"] = mask,
|
||
|
|
["gateway"] = gw,
|
||
|
|
["dns"] = dns
|
||
|
|
});
|
||
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
||
|
|
{
|
||
|
|
ShowResult(txtNetResult, result.Value<bool>("success") ? "保存成功,重启生效" : (result.Value<string>("error") ?? "失败"), result.Value<bool>("success"));
|
||
|
|
}));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|