Files
BR_YKC/上位机/YKC/Pages/GatewayPage.xaml.cs

228 lines
11 KiB
C#
Raw Permalink Normal View History

2026-05-21 12:56:29 +08:00
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"));
}));
});
}
}
}