Compare commits

...
68 Commits
Author SHA1 Message Date
Administrator 47317ca033 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-08-06 11:43:09 +08:00
Administrator 83cd4915d8 货架查询逻辑修改,编码错误修正 2026-08-06 11:43:06 +08:00
Administrator 25243c03e6 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-08-05 18:14:33 +08:00
Administrator b97bfab44f 料单总览数据去除Notes 2026-08-05 18:14:27 +08:00
sc 40f380f95f Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-07-19 13:43:02 +08:00
Administrator f8da62df7d Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-19 13:43:01 +08:00
Administrator ff289a0221 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-11 17:02:07 +08:00
Administrator a14f490032 添加统计日期选择功能 2026-07-11 17:02:03 +08:00
Administrator af28d6eba3 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-11 16:28:05 +08:00
Administrator f80d3f4950 查询页面单号输入空数据问题修复 2026-07-11 16:28:01 +08:00
Administrator 40392fccb4 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-10 16:49:05 +08:00
Administrator 95b61a35ac Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-10 16:49:04 +08:00
Administrator ad9cd88b41 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-10 16:21:45 +08:00
Administrator 0122e98b4d Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-10 16:21:42 +08:00
Administrator 7b0517c59c Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-03 14:47:41 +08:00
Administrator 18cc18740c Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-03 14:47:40 +08:00
Administrator 69f2a4e4ed Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-07-03 13:03:19 +08:00
Administrator ee07bb7eca AES 2026-07-03 13:03:16 +08:00
Administrator 5f3f2ab7bb Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-23 17:28:30 +08:00
sc 2af3cccba8 Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-23 17:28:28 +08:00
sc 6dbfa0610e Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 19:34:00 +08:00
sc 395f066568 Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 19:33:59 +08:00
sc 2e3f894a4d Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 19:04:27 +08:00
sc 9e94b03bc4 Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 19:04:25 +08:00
sc 9a3c8f0d80 Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 19:01:24 +08:00
sc c0e21f9752 Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 19:01:23 +08:00
sc 7cd46d11de Merge branch 'master' of http://192.168.0.12:13000/sc/SunlightAggregationTerminal 2026-06-21 18:40:00 +08:00
Administrator a72383e422 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-21 18:39:59 +08:00
Administrator c3c4bfcd68 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-13 00:36:55 +08:00
Administrator 164c229cb2 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-13 00:36:54 +08:00
Administrator ec1112f641 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 23:57:49 +08:00
Administrator aea7c945ae Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 23:57:48 +08:00
Administrator cdacabee03 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 22:28:52 +08:00
Administrator 94d1fb6a5d Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 22:28:49 +08:00
Administrator 130bfb9d7b Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 00:18:01 +08:00
Administrator c7afb21ddf Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 00:17:59 +08:00
Administrator 822fb19d28 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 00:17:38 +08:00
Administrator 0b2d726287 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-12 00:17:36 +08:00
Administrator 3ad3523631 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-11 00:36:09 +08:00
Administrator 78aab33698 输送次数消息 2026-06-11 00:36:06 +08:00
Administrator 61ac666002 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 23:26:52 +08:00
Administrator 9f5afa0fbd Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 23:26:50 +08:00
Administrator 809cecb54f Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 23:25:52 +08:00
Administrator cabba958f5 用户名和密码修改功能 2026-06-08 23:25:50 +08:00
Administrator 3852fc0142 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 18:51:51 +08:00
Administrator e52dd61baa 查询功能 2026-06-08 18:51:49 +08:00
Administrator 2d1d2bd6bc Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 01:16:23 +08:00
Administrator e4d0530cc3 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 01:16:10 +08:00
Administrator 5677817e55 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 01:13:45 +08:00
Administrator 06bbb5c8be Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-08 01:13:43 +08:00
Administrator 6d6bcb623c Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-07 01:26:25 +08:00
Administrator f100d5398c Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-07 01:26:22 +08:00
Administrator 0cc16df34c Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 23:32:42 +08:00
Administrator 3a84a4bdcc Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 23:32:40 +08:00
Administrator 2e44f1cfb7 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 23:12:51 +08:00
Administrator 70dabd0ca6 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 23:12:47 +08:00
Administrator ce3381e776 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 11:21:29 +08:00
Administrator 3f4a5a7cd8 细节信息页面修复 2026-06-06 11:21:27 +08:00
Administrator 663410c31f Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 00:29:47 +08:00
Administrator e0c949bde9 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-06 00:29:45 +08:00
Administrator cdbf09cd7f Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-04 00:02:18 +08:00
Administrator f11cb0f809 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-04 00:02:15 +08:00
Administrator 4af3fd5f46 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-03 00:36:50 +08:00
Administrator 2def1ca440 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-03 00:36:48 +08:00
Administrator 4fae724108 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-03 00:30:43 +08:00
Administrator b1070143a0 Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-03 00:30:41 +08:00
Administrator 5ac35c901d Merge branch 'master' of http://www.scserverddns.top:13000/sc/SunlightAggregationTerminal 2026-06-01 01:01:53 +08:00
Administrator a5f08f1f8e 公网访问相关 2026-06-01 00:52:20 +08:00
33 changed files with 1629 additions and 309 deletions

No files matched your search

+6
View File
@@ -31,6 +31,12 @@
Title="查询"
Icon="search.png"
ContentTemplate="{DataTemplate local:QueryPage}"/>
<!-- 操作页面 -->
<!--
<ShellContent
Title="操作"
Icon="IcOutlinePsychologyAlt.png"
ContentTemplate="{DataTemplate local:QueryPage}"/>-->
<!-- 3 通知页面 -->
<ShellContent
Title="通知"
+4 -4
View File
@@ -27,15 +27,15 @@ namespace SunlightAggregationTerminal
await Navigation.PushModalAsync(loading);
if (await AppModels.LogIn())
{//拒绝登陆时打开登录页面
{
await loading.Navigation.PopModalAsync();
}
else
{
else
{//拒绝登陆时打开登录页面
await loading.Navigation.PopModalAsync();
var logpage = new View.LogPage();
await Navigation.PushModalAsync(logpage);
await Navigation.PushModalAsync(new NavigationPage(logpage));
}
}
+79
View File
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.Intrinsics.X86;
using System.Security.Cryptography;
using System.Text;
namespace SunlightAggregationTerminal.Class
{
public class AES
{
public static string AesEncipher(string Key, string dat) //加密
{
//压缩
byte[] plainBytes = Compress( Encoding.UTF8.GetBytes(dat));
using var sha256 = System.Security.Cryptography.SHA256.Create();
using var aes = System.Security.Cryptography.Aes.Create();
aes.Key = sha256.ComputeHash(Encoding.UTF8.GetBytes(Key));
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.GenerateIV(); // 生成随机 IV
using var enc = aes.CreateEncryptor();
byte[] cipherBytes = enc.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
//将 IV (16字节) 和 密文 拼接成一个完整的字节数组
byte[] combinedBytes = new byte[aes.IV.Length + cipherBytes.Length];
Buffer.BlockCopy(aes.IV, 0, combinedBytes, 0, aes.IV.Length);
Buffer.BlockCopy(cipherBytes, 0, combinedBytes, aes.IV.Length, cipherBytes.Length);
return Convert.ToBase64String(combinedBytes);
}
public static string AesDecrypt(string Key, string dat)//解密
{
// 解码Base64
byte[] cipherBytes = Convert.FromBase64String(dat);
using var sha256 = System.Security.Cryptography.SHA256.Create();
using var aes = System.Security.Cryptography.Aes.Create();
aes.Key = sha256.ComputeHash(Encoding.UTF8.GetBytes(Key));
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// 从字节数组中提取前 16 字节作为 IV
aes.IV = cipherBytes.AsSpan(0, 16).ToArray();
using var dec = aes.CreateDecryptor();
// 解密
byte[] bytes = dec.TransformFinalBlock(cipherBytes, 16, cipherBytes.Length - 16);
//解压缩并返回
return Encoding.UTF8.GetString(Decompress(bytes));
}
// 3. Brotli 压缩辅助方法
private static byte[] Compress(byte[] data)
{
using var output = new MemoryStream();
using (var brotli = new BrotliStream(output, CompressionLevel.Optimal))
{
brotli.Write(data, 0, data.Length);
}
return output.ToArray();
}
// 4. Brotli 解压辅助方法
private static byte[] Decompress(byte[] data)
{
using var input = new MemoryStream(data);
using var brotli = new BrotliStream(input, CompressionMode.Decompress);
using var output = new MemoryStream();
brotli.CopyTo(output);
return output.ToArray();
}
}
}
+197 -84
View File
@@ -2,10 +2,13 @@
using SunlightAggregationTerminal.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using TouchSocket.Core;
namespace SunlightAggregationTerminal.Class
{
@@ -21,109 +24,219 @@ namespace SunlightAggregationTerminal.Class
}
public static string GetLocalIpSimple()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip))
{
return ip.ToString();
}
}
return "No network connection";
}
public static string ServerIP = "";
public static string ServerName = "";
public static string ServerPassword = "";
public static string ServerTerminal = "";
public static void Received(string dat)
{
try
{
Person deserializedPerson = JsonSerializer.Deserialize<Person>(dat)!;
var data = JsonSerializer.Deserialize<Dictionary<string, object>>(deserializedPerson.Dat);
// 获取当前设备上所有的网络接口
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
if (data != null)
foreach (var networkInterface in networkInterfaces)
{
//处理服务器发送信息
if (data.TryGetValue("Enterprise", out var val) && val != null) App.GlobalData.Enterprise = val.ToString() ?? "";
if (data.TryGetValue("Department", out val) && val != null) App.GlobalData.Department = val.ToString() ?? "";
if (data.TryGetValue("Groups", out val) && val != null) App.GlobalData.Groups = val.ToString() ?? "";
if (data.TryGetValue("UserName", out val) && val != null) App.GlobalData.UserName = val.ToString() ?? "";
if (data.TryGetValue("UserId", out val) && val != null)
{
App.GlobalData.UserId = val.ToString() ?? "";
App.GlobalData.LogNo = true;
// 仅检查处于活动状态的网络接口
if (networkInterface.OperationalStatus != OperationalStatus.Up)
continue;
Transmit("{\"Command\":\"Info\"}");
}
// 获取该接口下的所有单播 IP 地址
var addresses = networkInterface.GetIPProperties().UnicastAddresses;
if (data.TryGetValue("UserData", out var value_UserData))
foreach (var address in addresses)
{
}
if (data.TryGetValue("SysData", out var value_SysData))
{
}
if (data.TryGetValue("Info", out val) && val != null)//机台信息接受
{
DataModel.Info_data = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(val.ToString()!)!;
//发送消息
WeakReferenceMessenger.Default.Send(new object());
}
if (data.TryGetValue("Query", out val) && val != null)//查询接受
{
QueryPage.Query_data(val.ToString()!);
}
if (data.TryGetValue("QueryDetail", out val) && val != null)//查询接受
{
QueryDetail.Query_data(val.ToString()!);
}
if (data.TryGetValue("Notification", out val) && val != null)//信息通知接受
{
var dataNotification = JsonSerializer.Deserialize<Dictionary<string, object>>(val.ToString()!);
string _Title = "", _Content = "";
int _Type = 0;
if (dataNotification!.TryGetValue("Title", out var value_Notification_Title))
// 筛选条件:必须是 IPv4、非回环地址(127.x.x.x),且通常属于局域网网段
if (address.Address.AddressFamily == AddressFamily.InterNetwork &&
!IPAddress.IsLoopback(address.Address))
{
_Title = value_Notification_Title.ToString() ?? "";
return address.Address.ToString();
}
if (dataNotification!.TryGetValue("Content", out var value_Notification_Content))
{
_Content = value_Notification_Content.ToString() ?? "";
}
if (dataNotification!.TryGetValue("Type", out var value_Notification_Type))
{
string temp = value_Notification_Type?.ToString() ?? "";
// 转换
_Type = temp switch
{
"System" => 2,
"Message" => 1,
_ => 0
};
}
Models.AppModels.INSERT("INSERT INTO Notification (Title,Content,Time,Type)VALUES('" +
_Title + "','" + _Content + "','" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "','" + _Type + "');");
}
}
}
catch (Exception ex)
{
MainThread.BeginInvokeOnMainThread(() =>
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("", ex.Message.ToString(), "是");
Application.Current!.Windows[0].Page!.DisplayAlertAsync("获取IP地址失败", ex.Message.ToString(), "是");
});
}
return ""; // 如果未找到有效IP则返回null
}
public static string ServerIP = "";
public static string ServerURL = "";
public static string ServerName = "";
public static string ServerPassword = "";
public static string ServerTerminal = "";
public static void Received(string dat)
{
if (dat.Length < 6)
{
string inf;
switch (dat)
{
case "999":
inf = "不明错误";
break;
case "990":
inf = "拒接访问账户远程访问许可证过期";
break;
case "980":
inf = "目标对象服务器不存在或已离线";
break;
case "970":
inf = "目标对象服务器不存在或已离线";
break;
default:
inf = dat;
break;
}
// MainThread.BeginInvokeOnMainThread(() =>
// {
// Application.Current!.Windows[0].Page!.DisplayAlertAsync("", inf, "是");
// });
}
else
{
try
{
Person deserializedPerson = JsonSerializer.Deserialize<Person>(dat)!;
var data = JsonSerializer.Deserialize<Dictionary<string, object>>
(AES.AesDecrypt( deserializedPerson.Terminal,deserializedPerson.Dat));
if (data != null)
{
//处理服务器发送信息
if (data.TryGetValue("Enterprise", out var val) && val != null) App.GlobalData.Enterprise = val.ToString() ?? "";
if (data.TryGetValue("Department", out val) && val != null) App.GlobalData.Department = val.ToString() ?? "";
if (data.TryGetValue("Groups", out val) && val != null) App.GlobalData.Groups = val.ToString() ?? "";
if (data.TryGetValue("UserName", out val) && val != null) App.GlobalData.UserName = val.ToString() ?? "";
if (data.TryGetValue("UserId", out val) && val != null)
{
DataReceived.Transmit("{\"Command\":\"Info\"}");
App.GlobalData.UserId = val.ToString() ?? "";
App.GlobalData.LogNo = true;
}
if (data.TryGetValue("UserData", out var value_UserData))
{
}
if (data.TryGetValue("SysData", out var value_SysData))
{
var tmp = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(value_SysData.ToString()!)!;
}
if (data.TryGetValue("Info", out val) && val != null)//机台信息接受
{
DataModel.Info_data = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(val.ToString()!)!;
InfoPage.DyeMeasurementNumber = data.GetValue("DyeMeasurementNumber").ToString();
InfoPage.ChemicalNumber = data.GetValue("ChemicalNumber").ToString();
InfoPage.PowderNumber = data.GetValue("PowderNumber").ToString();
InfoPage.DyeDissolveNumber = data.GetValue("DyeDissolveNumber").ToString();
//发送消息
WeakReferenceMessenger.Default.Send(new object());
}
if (data.TryGetValue("ChemicalStatistics", out val) && val != null)//查询接受
{
InfoChemicalStatistics.Total_data(val.ToString()!);
}
if (data.TryGetValue("Query", out val) && val != null)//查询接受
{
QueryPage.Query_data(val.ToString()!);
}
if (data.TryGetValue("QueryDetail", out val) && val != null)//
{
QueryDetail.Query_data(val.ToString()!);
}
if (data.TryGetValue("InfoMachine", out val) && val != null)//
{
InfoDetail.Info_data(val.ToString()!, data.GetValue("Type").ToString()!);
}
if (data.TryGetValue("InfoMachineHistory", out val) && val != null)//
{
InfoDetail.Info_data(val.ToString()!, data.GetValue("Type").ToString()!);
}
if (data.TryGetValue("InfoMachinePipes", out val) && val != null)//
{
InfoDetail.Info_data(val.ToString()!, "00");
}
if (data.TryGetValue("Notification", out val) && val != null)//信息通知接受
{
var dataNotification = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(val.ToString()!);
string _Title = "", _Content = "";
int _Type = 0, _id = 0;
foreach (var dataNotificationrow in dataNotification!)
{
//解析信息
if (dataNotificationrow!.TryGetValue("id", out var value_Notification_id)
&& value_Notification_id != null)
{
_id = (int)value_Notification_id;
App.GlobalData.NotificationID = _id.ToString();
}
if (dataNotificationrow!.TryGetValue("Title", out var value_Notification_Title)
&& value_Notification_Title != null)
{
_Title = value_Notification_Title.ToString() ?? "";
}
if (dataNotificationrow!.TryGetValue("Content", out var value_Notification_Content)
&& value_Notification_Content != null)
{
_Content = value_Notification_Content.ToString() ?? "";
}
if (dataNotificationrow!.TryGetValue("Type", out var value_Notification_Type)
&& value_Notification_Type != null)
{
string temp = value_Notification_Type?.ToString() ?? "";
// 转换
_Type = temp switch
{
"System" => 2,
"Message" => 1,
_ => 0
};
}
if (_id != 0)
{
//记录信息到数据库
DataSet? Notificationdata = AppModels.Select("select * from Notification where Id = " + _id);
if (Notificationdata != null)
{
if (Notificationdata.Tables[0].Rows.Count == 0)
{
AppModels.INSERT("INSERT INTO Notification (Title,Content,Time,Type,Id)VALUES('" +
_Title + "','" + _Content + "','" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") +
"','" + _Type + "'," + _id + ");");
}
}
}
}
string sql = "UPDATE Users SET NotificationID = '" + App.GlobalData.NotificationID +
"'WHERE User='" + App.GlobalData.User + "';";
AppModels.Updata(sql);
}
if (data.TryGetValue("SETUSER", out val) && val != null)//信息通知接受
{
ProfilePage._data(data.GetValue("VALUE").ToString()!,data.GetValue("KEY").ToString()!);
}
}
}
catch (Exception ex)
{
MainThread.BeginInvokeOnMainThread(() =>
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("", ex.Message.ToString(), "是");
});
}
}
}
public static void Transmit(string Dat)
+101 -47
View File
@@ -17,7 +17,18 @@ namespace SunlightAggregationTerminal.Class
public static async void Configuration(string ip, string Name, string Password, string Terminal)
{
DataReceived.ServerIP = ip;
string[] parts = ip.Split('/');
if (parts.Length >= 2)
{
DataReceived.ServerIP = parts[0];
DataReceived.ServerURL = parts[1];
}
else
{
DataReceived.ServerIP = "";
DataReceived.ServerURL = "";
}
DataReceived.ServerName = Name;
DataReceived.ServerPassword = Password;
DataReceived.ServerTerminal = Terminal;
@@ -34,67 +45,88 @@ namespace SunlightAggregationTerminal.Class
public static async Task HttpClient(string url)
{
var config = new TouchSocketConfig();
#region Http设置远程服务器地址
config.SetRemoteIPHost("http://" + url);
#endregion
#region Http客户端获取断线通知
config.ConfigurePlugins(a =>
try
{
a.AddTcpClosedPlugin(async (c, e) =>
var config = new TouchSocketConfig();
#region Http设置远程服务器地址
config.SetRemoteIPHost("http://" + url);
#endregion
#region Http客户端获取断线通知
config.ConfigurePlugins(a =>
{
// 专门处理超时或主动取消的情况
MainThread.BeginInvokeOnMainThread(() =>
//处理连接断开
a.AddTcpClosedPlugin(async (c, e) =>
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("", "客户端断开连接", "是");
//MainThread.BeginInvokeOnMainThread(() =>
// {
// Application.Current!.Windows[0].Page!.DisplayAlertAsync("", "客户端断开连接", "是");
// });
// await e.InvokeNext();
});
//自动重连
a.UseReconnection<TouchSocket.Http.HttpClient>(options =>
{
options.PollingInterval = TimeSpan.FromSeconds(3);
});
//处理连接
a.AddTcpConnectedPlugin(async (c, e) =>
{
await e.InvokeNext();
});
await e.InvokeNext();
});
}); config.ConfigurePlugins(a =>
{
a.AddTcpConnectedPlugin(async (c, e) =>
{
HttpTransmit("{\"Command\":\"Log\"}");
await e.InvokeNext();
});
});
/*config.ConfigurePlugins(a =>
{
a.UseReconnection<TouchSocket.Http.HttpClient>(options =>
{
options.PollingInterval = TimeSpan.FromSeconds(3);
});
});*/
#endregion
#endregion
//配置config
await httpclient.SetupAsync(config);
//连接
await httpclient.ConnectAsync();
if (httpclient.Online)//是否重置客户端
{
await httpclient.CloseAsync();
}
//配置config
await httpclient.SetupAsync(config);
//连接
await httpclient.ConnectAsync();
HttpTransmit("{\"Command\":\"Log\"}");
}
catch (Exception ex)
{
MainThread.BeginInvokeOnMainThread(() =>
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("网络错误", ex.Message.ToString(), "是");
});
await httpclient.CloseAsync();
httpclient.Dispose();
}
}
/***发送信息处理***/
private static int HttpOutN=0;
public static async void HttpTransmit(string Dat)
{
if (!httpclient.Online) //检查连接
{
await httpclient.ConnectAsync();
}
var dat = new DataReceived.Person()
{
User = DataReceived.ServerName,
Password = DataReceived.ServerPassword,
Password = AES.AesEncipher(DataReceived.ServerTerminal, DataReceived.ServerPassword),
IP = DataReceived.GetLocalIpSimple(),
Terminal = DataReceived.ServerTerminal,
Dat = Dat
Dat = AES.AesEncipher(DataReceived.ServerTerminal, Dat),
};
var request = new HttpRequest();
request.SetContent(new StringHttpContent(JsonSerializer.Serialize(dat), Encoding.UTF8, "application/scjson"))
.InitHeaders()
.SetUrl("/H")
.SetUrl(DataReceived.ServerURL)
.SetHost(httpclient.RemoteIPHost.Host)
.AsPost();
// 创建一个超时操作,15秒后取消
using var cts = new CancellationTokenSource(1000 * 15);
using var cts = new CancellationTokenSource(1000 * 10);
try
{
using (var responseResult = await httpclient.RequestAsync(request, cts.Token))
@@ -107,23 +139,45 @@ namespace SunlightAggregationTerminal.Class
}
catch (OperationCanceledException)
{
// 专门处理超时或主动取消的情况
MainThread.BeginInvokeOnMainThread(() =>
if (HttpOutN >= 3)
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("网络错误", "网络请求超时,请检查网络或服务器状态。", "是");
});
HttpOutN = 0;
// 专门处理超时或主动取消的情况
MainThread.BeginInvokeOnMainThread(() =>
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("网络错误", "网络请求超时,请检查网络网络连接", "是");
});
await httpclient.CloseAsync();
httpclient.Dispose();
}
else
{
HttpTransmit(Dat);//回调
HttpOutN++;
}
}
catch (Exception ex)
{
MainThread.BeginInvokeOnMainThread(() =>
if (HttpOutN >= 3)
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("网络错误", ex.Message.ToString(), "是");
});
HttpOutN = 0;
MainThread.BeginInvokeOnMainThread(() =>
{
Application.Current!.Windows[0].Page!.DisplayAlertAsync("访问错误", ex.Message.ToString(), "是");
});
await httpclient.CloseAsync();
httpclient.Dispose();
}
else
{
HttpTransmit(Dat);//回调
HttpOutN++;
}
}
finally
{
}
}
}
}
+15 -2
View File
@@ -160,6 +160,12 @@ namespace SunlightAggregationTerminal.Class
string sql = "ALTER TABLE Users ADD COLUMN MessageNotificationMode BOOL DEFAULT (0);";
SQLitedata.ExecuteNonQuery(sql, null);
}
// 检查 NotificationID
if (!existingColumns.Contains("NotificationID"))
{
string sql = "ALTER TABLE Users ADD COLUMN NotificationID TEXT;";
SQLitedata.ExecuteNonQuery(sql, null);
}
// 检查 GUID
if (!existingColumns.Contains("GUID"))
{
@@ -215,7 +221,13 @@ namespace SunlightAggregationTerminal.Class
{
string sql = "ALTER TABLE Notification ADD COLUMN Type INT;";
SQLitedata.ExecuteNonQuery(sql, null);
}
}
// 检查 id
if (!existingColumns.Contains("Id"))
{
string sql = "ALTER TABLE Notification ADD COLUMN Id INTEGER PRIMARY KEY;";
SQLitedata.ExecuteNonQuery(sql, null);
}
}
}
private static void CheckAndRepairTableSchemaSERVER()
@@ -284,6 +296,7 @@ namespace SunlightAggregationTerminal.Class
LocalAreaNetworkMode BOOL DEFAULT (0),
DarkMode BOOL DEFAULT (0),
MessageNotificationMode BOOL DEFAULT (0),
NotificationID TEXT,
GUID TEXT
);";
@@ -302,7 +315,7 @@ namespace SunlightAggregationTerminal.Class
// 建表语句
string createSql = @"
CREATE TABLE Notification (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Id INTEGER PRIMARY KEY,
Title TEXT,
Content TEXT,
Time TEXT,
+1 -1
View File
@@ -87,7 +87,7 @@ namespace SunlightAggregationTerminal.Class
{
await tcpClient.SetupAsync(new TouchSocketConfig()
.SetSingleStreamDataHandlingAdapter(() => new PeriodPackageAdapter())//以超时周期和包
.SetRemoteIPHost(ip)
.SetRemoteIPHost(ip)
.ConfigurePlugins(a =>
{
a.UseReconnection<TouchSocket.Sockets.TcpClient>(options =>
+1 -1
View File
@@ -18,7 +18,7 @@ namespace SunlightAggregationTerminal.Converters
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// 单向绑定通常不需要实现,除非你需要双向绑定
// 单向绑定
throw new NotImplementedException();
}
}
-1
View File
@@ -31,7 +31,6 @@ namespace SunlightAggregationTerminal.Converters
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// 通常图片转回字符串在 UI 上很少用到,可以抛出异常或留空
throw new NotImplementedException();
}
}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="currentColor" d="M19.94 9.06C19.5 5.73 16.57 3 13 3C9.47 3 6.57 5.61 6.08 9l-1.93 3.48c-.41.66.07 1.52.85 1.52h1v2c0 1.1.9 2 2 2h1v3h7v-4.68a7.02 7.02 0 0 0 3.94-7.26m-5.05 5.57l-.89.42V19h-3v-3H8v-4H6.7l1.33-2.33C8.21 7.06 10.35 5 13 5c2.76 0 5 2.24 5 5c0 2.09-1.29 3.88-3.11 4.63"/><path fill="currentColor" d="M12.5 12.54c-.41 0-.74.31-.74.73c0 .41.33.74.74.74c.42 0 .73-.33.73-.74a.71.71 0 0 0-.73-.73m0-5.54c-1.03 0-1.74.67-2 1.45l.96.4c.13-.39.43-.86 1.05-.86c.95 0 1.13.89.8 1.36c-.32.45-.86.75-1.14 1.26c-.23.4-.18.87-.18 1.16h1.06c0-.55.04-.65.13-.82c.23-.42.65-.62 1.09-1.27c.4-.59.25-1.38-.01-1.8c-.31-.49-.9-.88-1.76-.88"/></svg>

After

Width:  |  Height:  |  Size: 738 B

+70
View File
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SunlightAggregationTerminal.InfoChemicalStatistics"
Title="耗用统计">
<Grid>
<Grid RowDefinitions="Auto, *" >
<Grid ColumnDefinitions="*, Auto" Grid.Row="0" Grid.Column="0" Margin="5">
<HorizontalStackLayout Grid.Row="0" Grid.Column="0" Margin="5,0,0,0" >
<DatePicker x:Name="StartTime" Format="yyyy年MM月dd日" FontSize="16"
MaximumWidthRequest="150" MinimumWidthRequest="130" WidthRequest="135"/>
<Label Text="~" FontSize="28"/>
<DatePicker x:Name="EndTime" Format="yyyy年MM月dd日" FontSize="16"
MaximumWidthRequest="150" MinimumWidthRequest="130" WidthRequest="135"/>
</HorizontalStackLayout>
<Button Grid.Row="0" Grid.Column="1" Text="查询" Clicked="Button_Clicked"
WidthRequest="60" Padding="5,0,5,0" Margin="20,0,0,5" />
</Grid>
<CollectionView Grid.Row="1" x:Name="CardCollectionView">
<!-- 保持滚动条 -->
<CollectionView.ItemTemplate>
<DataTemplate>
<!-- 这里定义单个卡片的 UI 结构 -->
<Border BackgroundColor="White" Stroke="#CCCCCC"
StrokeThickness="2" Margin="10,0,10,10"
StrokeShape="RoundRectangle 10">
<VerticalStackLayout>
<!-- 设备信息 -->
<HorizontalStackLayout>
<Label Text="原料: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding ProductName}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="代码: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding ProductCode}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="用量: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding TotalDispenseGrams}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="Kg" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
<!-- 查询中动画页面 -->
<Grid x:Name="LoadingIndicator" BackgroundColor="Gray"
IsVisible="False" Opacity="0.9">
<VerticalStackLayout Padding="30" Spacing="10"
VerticalOptions="Center"
HorizontalOptions="Center">
<ActivityIndicator IsRunning="True"
Color="#512BD4"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text="查询中..." FontAttributes="Bold"
FontSize="24" TextColor="Black"/>
</VerticalStackLayout>
</Grid>
</Grid>
</ContentPage>
+89
View File
@@ -0,0 +1,89 @@
using SunlightAggregationTerminal.Class;
using SunlightAggregationTerminal.Models;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Text.Json;
using TouchSocket.Core;
namespace SunlightAggregationTerminal;
public partial class InfoChemicalStatistics : ContentPage
{
public class ChemicalTotal
{
public string? ProductName { get; set; }
public string? ProductCode { get; set; }
public float? TotalDispenseGrams { get; set; }
}
public static ObservableCollection<ChemicalTotal> ChemicalTotals { get; set; } = new();
public InfoChemicalStatistics()
{
InitializeComponent();
Dictionary<string, object> Dictionary = new Dictionary<string, object>();
Dictionary.Add("Command", "ChemicalStatistics");
DateTime StartTimee_ = (DateTime)StartTime.Date!;
Dictionary.Add("StartTime", StartTimee_.ToString("yyyy-MM-dd"));
DateTime EndTime_ = (DateTime)EndTime.Date!;
Dictionary.Add("EndTime", EndTime_.AddDays(1).ToString("yyyy-MM-dd"));
Total_Command(Dictionary.ToJsonString());
}
public async void Total_Command(string dat)
{
LoadingIndicator.IsVisible = true;
ChemicalTotals.Clear();
DataReceived.Transmit(dat);
// 创建一个 15 秒的延时任务
Task delayTask = Task.Delay(15000);
// 创建一个监测任务,不断检查变量
Task monitorTask = Task.Run(async () =>
{
while (ChemicalTotals.Count == 0)
{
// 每隔 100 毫秒检查一次,避免 CPU 占用过高
await Task.Delay(100);
}
});
// 使用 Task.WhenAny 等待任意一个任务完成
await Task.WhenAny(delayTask, monitorTask);
CardCollectionView.ItemsSource = ChemicalTotals;
LoadingIndicator.IsVisible = false;
}
public static void Total_data(string dat)
{
try
{
var data = JsonSerializer.Deserialize<List<ChemicalTotal>>(dat);
if (data != null)
{
foreach (var item in data)
{
item.TotalDispenseGrams = MathF.Round((float)item.TotalDispenseGrams! / 1000, 5);
ChemicalTotals.Add(item);
}
}
}
catch (Exception)
{
}
}
//搜索按钮
private void Button_Clicked(object sender, EventArgs e)
{
Dictionary<string, object> Dictionary = new Dictionary<string, object>();
Dictionary.Add("Command", "ChemicalStatistics");
DateTime StartTimee_ = (DateTime)StartTime.Date!;
Dictionary.Add("StartTime", StartTimee_.ToString("yyyy-MM-dd"));
DateTime EndTime_ = (DateTime)EndTime.Date!;
Dictionary.Add("EndTime", EndTime_.AddDays(1).ToString("yyyy-MM-dd"));
Total_Command(Dictionary.ToJsonString());
}
}
+55 -36
View File
@@ -3,10 +3,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SunlightAggregationTerminal.InfoDetail"
xmlns:converters="clr-namespace:SunlightAggregationTerminal.Converters"
Title="细节信息">
Title="细节信息"
Loaded="ContentPage_Loaded">
<ContentPage.Resources>
<ResourceDictionary>
<converters:StringToImageConverter x:Key="StringToImageConverter" />
<converters:StringToBoolConverter x:Key="StringToBoolConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid RowDefinitions="Auto, Auto, *" ColumnDefinitions="*, Auto" >
@@ -43,23 +45,25 @@
<Button Text="远程控制" Clicked="Button_control" BackgroundColor="Transparent" TextColor="Black"/>
</HorizontalStackLayout>
</Grid>
<Grid x:Name="_real" Grid.Row="2" Grid.Column="0" >
<VerticalStackLayout VerticalOptions="Center">
<!-- 设备信息 -->
<Label Text="{Binding ModelA}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelA, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelB}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelB, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelC}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelC, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelD}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelD, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelE}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelE, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelF}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelF, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding Information}" FontAttributes="Bold" FontSize="22" TextColor="Black"/>
</VerticalStackLayout>
<Grid x:Name="_real" Grid.Row="2" Grid.Column="0" BackgroundColor="#F0F0F0">
<!-- 设备信息 -->
<RefreshView x:Name="myCardCollectionView_" >
<CollectionView x:Name="CardCollectionView_inf" RemainingItemsThreshold="5">
<CollectionView.ItemTemplate>
<DataTemplate>
<Border BackgroundColor="White" Stroke="#CCCCCC"
StrokeThickness="2" Margin="10,0,10,10" StrokeShape="RoundRectangle 10">
<VerticalStackLayout VerticalOptions="Center">
<HorizontalStackLayout>
<Label Text="{Binding inf}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
</Grid>
<!-- 设备内容 -->
@@ -88,10 +92,7 @@
<Label Text="{Binding ProductState}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<BoxView HeightRequest="3" Color="#CCCCCC" />
<HorizontalStackLayout>
<Label Text="信息: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding ProductInf}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
@@ -120,30 +121,36 @@
FontSize="22" TextColor="Black"/>
<Label Text="{Binding ReDye}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text=" 步骤" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding Step}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="染机: " FontAttributes="Bold"
<Label Text="步骤: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding Machine}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="时间: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding EndTime}" FontAttributes="Bold"
<Label Text="{Binding StepNumber}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<BoxView HeightRequest="3" Color="#CCCCCC" />
<HorizontalStackLayout>
<Label Text="信息: " FontAttributes="Bold"
<Label Text="{Binding Notes}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="呼叫时间: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding Information}" FontAttributes="Bold"
<Label Text="{Binding CallTime}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="开始时间: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding DispenseStartTime}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="完成时间: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding DispenseEndTime}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</VerticalStackLayout>
</Border>
</DataTemplate>
@@ -155,6 +162,18 @@
<Grid x:Name="_control" IsVisible="False" Grid.Row="2" Grid.Column="0" BackgroundColor="#F0F0F0">
</Grid>
<Grid x:Name="LoadingIndicator" Grid.Row="2" Grid.Column="0"
BackgroundColor="Gray" IsVisible="False" Opacity="0.9">
<VerticalStackLayout Padding="30" Spacing="10"
VerticalOptions="Center"
HorizontalOptions="Center">
<ActivityIndicator IsRunning="True"
Color="#512BD4"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text="查询中..." FontAttributes="Bold"
FontSize="24" TextColor="Black"/>
</VerticalStackLayout>
</Grid>
</Grid>
</ContentPage>
+555 -12
View File
@@ -1,29 +1,124 @@
using CommunityToolkit.Mvvm.ComponentModel;
using SunlightAggregationTerminal.Class;
using SunlightAggregationTerminal.Models;
using System.Collections.ObjectModel;
using System.Data;
using System.Reflection.PortableExecutable;
using System.Text.Json;
using TouchSocket.Core;
namespace SunlightAggregationTerminal;
public partial class InfoDetail : ContentPage
public class InfoMachineItem
{
public string? inf { get; set; }
}public partial class InfoDetail : ContentPage
{
public static ObservableCollection<ProbuctItem> InfoProbuctItems { get; set; } = new();
public static ObservableCollection<DyelotDetailsItem> InfoDyelotDetailsItems { get; set; } = new();
public static ObservableCollection<DyelotDetailsItem> InfoDyelotHistoryItems { get; set; } = new();
public static ObservableCollection<InfoMachineItem> InfoMachineItems { get; set; } = new();
public static InfoItem infoItem=new();
private DateTime _lastRefreshTime = DateTime.MinValue;
public InfoDetail(InfoItem item)
{
InitializeComponent();
this.BindingContext = item;
InfoProbuctItems.Add(new ProbuctItem { ProductName="cs", ProductCode="cs", ProductState="", ProductInf="" });
InfoProbuctItems.Add(new ProbuctItem { ProductName = "c23s", ProductCode = "cweds", ProductState = "", ProductInf = "" });
CardCollectionView_machine.ItemsSource = InfoProbuctItems;
CardCollectionView_history.ItemsSource = InfoDyelotDetailsItems;
infoItem = item;
myCardCollectionView_.Refreshing += (sender, e) => {
// 防抖判断:如果距离上次刷新不足5秒,直接取消本次操作
if ((DateTime.Now - _lastRefreshTime).TotalSeconds < 1)
{
myCardCollectionView_.IsRefreshing = false;
return;
}
try
{
// 更新刷新时间
_lastRefreshTime = DateTime.Now;
InfoMachine();
myCardCollectionView_.IsRefreshing = false;
}
catch (Exception)
{
}
};
}
private void ContentPage_Loaded(object sender, EventArgs e)
{
InfoMachine();
InfoMachineItems.Clear();
InfoProbuctItems.Clear();
InfoDyelotHistoryItems.Clear();
CardCollectionView_inf.ItemsSource = InfoMachineItems;
CardCollectionView_machine.ItemsSource = InfoProbuctItems;
CardCollectionView_history.ItemsSource = InfoDyelotHistoryItems;
}
//查询
private void InfoMachine() {
Dictionary<string, object> data_ = new Dictionary<string, object>();
data_.Add("Command", "InfoMachine");
if (infoItem.Model == "252")
{
data_.Add("Type", "10");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "252-2T")
{
data_.Add("Type", "10");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "252RB")
{
data_.Add("Type", "10");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "252RDRM")
{
data_.Add("Type", "12");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "242W")
{
data_.Add("Type", "10");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "302")
{
data_.Add("Type", "20");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "303")
{
data_.Add("Type", "20");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
else if (infoItem.Model == "303PDW")
{
data_.Add("Type", "20");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_Command(data_.ToJsonString());
}
}
//设备信息
private void Button_real(object sender, EventArgs e)
{
@@ -34,12 +129,28 @@ public partial class InfoDetail : ContentPage
}
//设备内容
private void Button_machine(object sender, EventArgs e)
private async void Button_machine(object sender, EventArgs e)
{
_real.IsVisible = false;
_machine.IsVisible = true;
_history.IsVisible = false;
_control.IsVisible = false;
if (infoItem.Model == "252" || infoItem.Model == "252-2T" ||
infoItem.Model == "252RB" || infoItem.Model == "242W" ||
infoItem.Model == "252RDRM")
{
await DisplayAlertAsync("限制", "当前功能暂不可用", "是");
return;
}
if (InfoProbuctItems.Count == 0)
{
Dictionary<string, object> data_ = new Dictionary<string, object>();
data_.Add("Command", "InfoMachinePipes");
data_.Add("MachinName", infoItem.Machine!);
Query_Probuct(data_.ToJsonString());
}
}
//历史
@@ -49,6 +160,67 @@ public partial class InfoDetail : ContentPage
_machine.IsVisible = false;
_history.IsVisible = true;
_control.IsVisible = false;
if (InfoDyelotHistoryItems.Count == 0)
{
Dictionary<string, object> data_ = new Dictionary<string, object>();
data_.Add("Command", "InfoMachineHistory");
if (infoItem.Model == "252")
{
data_.Add("Type", "80");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "252-2T")
{
data_.Add("Type", "80");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "252RB")
{
data_.Add("Type", "80");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "252RDRM")
{
data_.Add("Type", "82");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "242W")
{
data_.Add("Type", "80");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "302")
{
data_.Add("Type", "90");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "303")
{
data_.Add("Type", "90");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
else if (infoItem.Model == "303PDW")
{
data_.Add("Type", "90");
data_.Add("Field", "*");
data_.Add("MachinName", infoItem.Machine!);
Query_History(data_.ToJsonString());
}
}
}
//远程
@@ -60,4 +232,375 @@ public partial class InfoDetail : ContentPage
_control.IsVisible = true;
await DisplayAlertAsync("限制", "当前功能暂不可用", "是");
}
//发送请求
public async void Query_Command(string dat)
{
LoadingIndicator.IsVisible = true;
InfoMachineItems.Clear();
DataReceived.Transmit(dat);
// 创建一个 秒的延时任务
Task delayTask = Task.Delay(10000);
// 创建一个监测任务,不断检查变量
Task monitorTask = Task.Run(async () =>
{
while (InfoMachineItems.Count == 0)
{
// 每隔 100 毫秒检查一次,避免 CPU 占用过高
await Task.Delay(1000);
}
});
// 使用 Task.WhenAny 等待任意一个任务完成
await Task.WhenAny(delayTask, monitorTask);
LoadingIndicator.IsVisible = false;
}
public async void Query_Probuct(string dat)
{
LoadingIndicator.IsVisible = true;
InfoProbuctItems.Clear();
DataReceived.Transmit(dat);
// 创建一个 秒的延时任务
Task delayTask = Task.Delay(10000);
// 创建一个监测任务,不断检查变量
Task monitorTask = Task.Run(async () =>
{
while (InfoProbuctItems.Count == 0)
{
// 每隔 100 毫秒检查一次,避免 CPU 占用过高
await Task.Delay(1000);
}
});
// 使用 Task.WhenAny 等待任意一个任务完成
await Task.WhenAny(delayTask, monitorTask);
LoadingIndicator.IsVisible = false;
}
public async void Query_History(string dat)
{
LoadingIndicator.IsVisible = true;
InfoDyelotHistoryItems.Clear();
DataReceived.Transmit(dat);
// 创建一个 秒的延时任务
Task delayTask = Task.Delay(10000);
// 创建一个监测任务,不断检查变量
Task monitorTask = Task.Run(async () =>
{
while (InfoDyelotHistoryItems.Count == 0)
{
// 每隔 100 毫秒检查一次,避免 CPU 占用过高
await Task.Delay(1000);
}
});
// 使用 Task.WhenAny 等待任意一个任务完成
await Task.WhenAny(delayTask, monitorTask);
LoadingIndicator.IsVisible = false;
}
public static void Info_data(string dat, string id)
{
var data = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(dat)!;
//助剂原料查询
if (id == "00")
{
foreach (var item in data!)
{
ProbuctItem probuctItem = new ProbuctItem();
probuctItem.ProductCode = SafeGet(item, "ProductCode");
probuctItem.ProductName = SafeGet(item, "ProductName");
if (item.GetValue("Enabled").ToString()! == "1")
{
probuctItem.ProductState = "启用";
}
else { probuctItem.ProductState = "停用"; }
if (item!.TryGetValue("No", out var _No) && _No != null)
{
probuctItem.ProductInf = "管路: " + _No + "\n";
}
if (item!.TryGetValue("MinLimit", out var _MinLimit) && _MinLimit != null)
{
probuctItem.ProductInf = probuctItem.ProductInf+"最少量: " + _MinLimit + "g\n";
}
if (item!.TryGetValue("MaxLimit", out var _MaxLimit) && _MaxLimit != null)
{
probuctItem.ProductInf = probuctItem.ProductInf + "最大量: " + _MinLimit + "g\n";
}
if (item!.TryGetValue("Conc", out var _Conc) && _Conc != null)
{
probuctItem.ProductInf = probuctItem.ProductInf + "浓度: " + _Conc + "\n";
}
if (item!.TryGetValue("Enabled", out var _Gravity) && _Gravity != null)
{
probuctItem.ProductInf = probuctItem.ProductInf + "比重: " + _Gravity;
}
InfoProbuctItems.Add(probuctItem);
}
if (InfoProbuctItems.Count == 0) InfoProbuctItems.Add(new ProbuctItem());
}
//染料查询
else if (id == "10")
{
foreach (var item in data!)
{
string inf_ = "染机: " + SafeGet(item, "Machine")+ "\n";
inf_ = inf_ + "料单: " + SafeGet(item, "Dyelot");
inf_ = inf_ + "@" + SafeGet(item, "ReDye") + "\n";
inf_ = inf_ + "步骤: " + SafeGet(item, "StepNumber") + "\n";
inf_ = inf_ + "流程: " + SafeGet(item, "Process") + "\n";
inf_ = inf_ + "化料桶: " + SafeGet(item, "TankNO") + "\n";
inf_ = inf_ + "染料桶数: " + SafeGet(item, "TotalNumber");
if (item!.TryGetValue("BarrelState", out var _Type) && _Type != null)
{
string temp = _Type?.ToString() ?? "";
// 转换
_Type = temp switch
{
"301" => "就绪",
"309" => "未准备",
_ => "无信息"
};
inf_ = inf_ + _Type;
}
inf_ = inf_ + "状态: " + SafeGet(item, "State") + "\n";
InfoMachineItem infoMachineItem = new InfoMachineItem();
infoMachineItem.inf = inf_;
InfoMachineItems.Add(infoMachineItem);
}
if (InfoMachineItems.Count == 0) InfoMachineItems.Add(new InfoMachineItem());
}
//染料查询化料货架
else if (id == "12")
{
foreach (var item in data!)
{
string inf_ = "位置: " + SafeGet(item, "Position") + "\n";
inf_ = inf_ + "料单: " + SafeGet(item, "Dyelot");
inf_ = inf_ + "@" + SafeGet(item, "ReDye") + "\n";
inf_ = inf_ + "步骤: " + SafeGet(item, "StepNumber") + "\n";
if (item!.TryGetValue("BarrelType", out var _Type) && _Type != null)
{
string temp = _Type?.ToString() ?? "";
// 转换
_Type = temp switch
{
"1" => "空桶",
"2" => "染料桶",
_ => "无桶"
};
inf_ = inf_ + "类型:" + _Type;
}
if (item!.TryGetValue("BarrelState", out var _BarrelState) && _BarrelState != null)
{
string temp = _BarrelState?.ToString() ?? "";
_BarrelState = temp switch
{
"201" => "[分桶]",
_ => ""
};
inf_ = inf_ + _BarrelState;
}
inf_ = inf_ + "[" + SafeGet(item, "Barrelserialnumber") + "]\n";
inf_ = inf_ + "上架时间: " + DateTime.Parse(item.GetValue("Createtime").ToString() ?? "")
.ToString("yyyy-MM-dd HH:mm:ss") + "\n";
inf_ = inf_ + "状态 [" + SafeGet(item, "State") + "]";
InfoMachineItem infoMachineItem = new InfoMachineItem();
infoMachineItem.inf = inf_;
InfoMachineItems.Add(infoMachineItem);
}
if (InfoMachineItems.Count == 0) InfoMachineItems.Add(new InfoMachineItem());
}
//助剂查询
else if (id == "20")
{
foreach (var item in data!)
{
string inf_ = "染机: " + SafeGet(item, "Machine") + "\n";
inf_ = inf_ + "料单: " + SafeGet(item, "Dyelot");
inf_ = inf_ + "@" + SafeGet(item, "ReDye") + "\n";
inf_ = inf_ + "步骤: " + SafeGet(item, "StepNumber") + "\n";
inf_ = inf_ + "总浴量: " + SafeGet(item, "Volume")+ "\n";
inf_ = inf_ + "计量模组: " + SafeGet(item, "DispenseModule") + "\n";
if (item!.TryGetValue("TankNo", out var _TankNo) && _TankNo != null)
{
inf_ = inf_ + "目标位置: " + item.GetValue("TankNo") + "\n";
}
else {
inf_ = inf_ + "目标位置: 未指定\n" ;
}
inf_ = inf_ + "开始时间: " + DateTime.Parse(item.GetValue("DispenseStartTime").ToString() ?? "")
.ToString("yyyy-MM-dd HH:mm:ss") + "\n";
if (item!.TryGetValue("State", out var _Type) && _Type != null)
{
string temp = _Type?.ToString() ?? "";
// 转换
_Type = temp switch
{
"102" => "计量中",
"301" => "完成",
"309" => "异常",
_ => "无信息"
};
inf_ = inf_ + "状态: " + _Type;
}
InfoMachineItem infoMachineItem = new InfoMachineItem();
infoMachineItem.inf = inf_;
if (!InfoMachineItems.Any(x => x.inf == inf_))
{
InfoMachineItems.Add(infoMachineItem);
}
}
if (InfoMachineItems.Count==0) InfoMachineItems.Add(new InfoMachineItem());
}
//化料历史信息查询
else if (id == "80")
{
foreach (var item in data!)
{
DyelotDetailsItem dyelotDetailsItem = new DyelotDetailsItem();
dyelotDetailsItem.Dyelot = SafeGet(item,"Dyelot");
dyelotDetailsItem.ReDye = int.Parse(SafeGet(item, "ReDye"));
dyelotDetailsItem.StepNumber = int.Parse(SafeGet(item, "StepNumber"));
dyelotDetailsItem.Notes = "染机: " + SafeGet(item, "Machine") + "\n";
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes +
"流程: " + SafeGet(item, "Process") + "\n";
if (item!.TryGetValue("State", out var _State) && _State != null)
{
string temp = _State?.ToString() ?? "";
// 转换
_State = temp switch
{
"301" => "完成",
"309" => "异常",
_ => "无信息"
};
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "状态: " + _State ;
}
if (item!.TryGetValue("TankNo", out var _TankNo) && _TankNo != null)
{
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + " [化料桶T" + _TankNo + "]";
}
if (item!.TryGetValue("TotalNumber", out var _TotalNumber) && _TotalNumber != null)
{
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + " [" + _TotalNumber+"桶]";
}
dyelotDetailsItem.DispenseStartTime = SafeGet(item, "DispenseStartTime", "T").Replace("T", " ");
dyelotDetailsItem.DispenseEndTime = SafeGet(item, "DispenseEndTime", "T").Replace("T", " ");
if (item!.TryGetValue("CallTime", out var _CallTime) && _CallTime != null)
{
if (DateTime.TryParse(_CallTime.ToString(), out DateTime dtc))
{
dyelotDetailsItem.CallTime = dtc.ToString("yyyy-MM-dd HH:mm:ss");
}
}
InfoDyelotHistoryItems.Add(dyelotDetailsItem);
}
if (InfoDyelotHistoryItems.Count == 0) InfoDyelotHistoryItems.Add(new DyelotDetailsItem());
}
//化料货架历史信息查询
else if (id == "82")
{
foreach (var item in data!)
{
DyelotDetailsItem dyelotDetailsItem = new DyelotDetailsItem();
dyelotDetailsItem.Dyelot = SafeGet(item, "Dyelot");
dyelotDetailsItem.ReDye = int.Parse(SafeGet(item, "ReDye"));
dyelotDetailsItem.StepNumber = int.Parse(SafeGet(item, "StepNumber"));
dyelotDetailsItem.Notes = "位置: " + SafeGet(item, "Position") + "\n";
if (item!.TryGetValue("BarrelType", out var _Type) && _Type != null)
{
string temp = _Type?.ToString() ?? "";
// 转换
_Type = temp switch
{
"1" => "空桶",
"2" => "染料桶",
_ => "无桶"
};
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "类型: " + _Type;
}
if (item!.TryGetValue("BarrelState", out var _BarrelState) && _BarrelState != null)
{
string temp = _BarrelState?.ToString() ?? "";
_BarrelState = temp switch
{
"201" => "[分桶]",
_ => ""
};
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + _BarrelState;
}
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "[" + SafeGet(item, "Barrelserialnumber") + "]\n";
if (item!.TryGetValue("State", out var _State) && _State != null)
{
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "状态: " + _State;
}
dyelotDetailsItem.DispenseStartTime = SafeGet(item, "CreateTime", "T").Replace("T", " ");
dyelotDetailsItem.DispenseEndTime = "";
dyelotDetailsItem.UsageTime = SafeGet(item , "CreateTime","T").Replace("T", " ");
dyelotDetailsItem.CallTime = SafeGet(item, "CreateTime", "T").Replace("T", " ");
InfoDyelotHistoryItems.Add(dyelotDetailsItem);
}
if (InfoDyelotHistoryItems.Count == 0) InfoDyelotHistoryItems.Add(new DyelotDetailsItem());
}
//助剂历史信息查询
else if (id == "90")
{
foreach (var item in data!)
{
DyelotDetailsItem dyelotDetailsItem = new DyelotDetailsItem();
dyelotDetailsItem.Dyelot = SafeGet(item, "Dyelot");
dyelotDetailsItem.ReDye = int.Parse(SafeGet(item, "ReDye"));
dyelotDetailsItem.StepNumber = int.Parse(SafeGet(item, "StepNumber"));
dyelotDetailsItem.Notes = "染机: " + SafeGet(item, "Machine") + "\n";
if (item!.TryGetValue("State", out var _State) && _State != null)
{
string temp = _State?.ToString() ?? "";
// 转换
_State = temp switch
{
"301" => "完成",
"309" => "异常",
_ => "无信息"
};
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "状态: " + _State;
}
dyelotDetailsItem.DispenseStartTime = SafeGet(item, "DispenseStartTime", "T").Replace("T", " ");
dyelotDetailsItem.DispenseEndTime = SafeGet(item, "DispenseEndTime", "T").Replace("T", " ");
if (item!.TryGetValue("CallTime", out var _CallTime) && _CallTime != null)
{
if (DateTime.TryParse(_CallTime.ToString(), out DateTime dtc))
{
dyelotDetailsItem.CallTime = dtc.ToString("yyyy-MM-dd HH:mm:ss");
}
}
InfoDyelotHistoryItems.Add(dyelotDetailsItem);
}
if (InfoDyelotHistoryItems.Count == 0) InfoDyelotHistoryItems.Add(new DyelotDetailsItem());
}
}
// 辅助查询方法
private static string SafeGet(Dictionary<string, object> item, string key, string defaultValue = "0")
{
//获取值并检查
if (item!.TryGetValue(key, out var _dat) && _dat != null)
{
return _dat.ToString()!;
}
else
{
return defaultValue;
}
}
}
+126 -65
View File
@@ -2,7 +2,7 @@
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SunlightAggregationTerminal.InfoPage"
xmlns:converters="clr-namespace:SunlightAggregationTerminal.Converters"
xmlns:converters="clr-namespace:SunlightAggregationTerminal.Converters"
Title="设备信息">
<ContentPage.Resources>
<ResourceDictionary>
@@ -12,73 +12,134 @@
</ContentPage.Resources>
<RefreshView x:Name="myRefreshView_" >
<CollectionView x:Name="CardCollectionView">
<!-- 保持滚动条 -->
<CollectionView.ItemTemplate>
<DataTemplate>
<!-- 这里定义单个卡片的 UI 结构 -->
<Border BackgroundColor="White" Stroke="#CCCCCC"
<CollectionView.Header>
<Border BackgroundColor="White"
Stroke="#CCCCCC"
Margin="10,0,10,10"
StrokeThickness="5"
StrokeShape="RoundRectangle 10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="今日输送信息" Grid.Row="0" BackgroundColor="#CCCCCC"
FontAttributes="Bold" FontSize="24" TextColor="Black" Padding="5"/>
<Grid Grid.Row="1" ColumnDefinitions="Auto,*,Auto" Padding="5" ColumnSpacing="5">
<HorizontalStackLayout>
<!-- 图片 -->
<Image WidthRequest="100" HeightRequest="100" Source="sunlightlogo.png"/>
<!-- 设备状态文字内容 -->
<VerticalStackLayout Grid.Column="1" VerticalOptions="Center">
<ContentView>
<HorizontalStackLayout VerticalOptions="Center">
<Label Text="染料称量(次): " FontAttributes="Bold"
FontSize="20" TextColor="Black"/>
<Label x:Name="_DyeMeasurementNumber" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</ContentView>
<ContentView>
<HorizontalStackLayout VerticalOptions="Center">
<Label Text="染料输送(次): " FontAttributes="Bold"
FontSize="20" TextColor="Black"/>
<Label x:Name="_DyeDissolveNumber" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</ContentView>
<ContentView>
<HorizontalStackLayout VerticalOptions="Center">
<Label Text="助剂输送(次): " FontAttributes="Bold"
FontSize="20" TextColor="Black"/>
<Label x:Name="_ChemicalNumber" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</ContentView>
<ContentView>
<HorizontalStackLayout VerticalOptions="Center">
<Label Text="粉剂输送(次): " FontAttributes="Bold"
FontSize="20" TextColor="Black"/>
<Label x:Name="_PowderNumber" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</ContentView>
</VerticalStackLayout>
</HorizontalStackLayout>
</Grid>
</Grid>
<!-- 点击事件 -->
<Border.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_ChemicalStatistics"/>
</Border.GestureRecognizers>
</Border>
</CollectionView.Header>
<!-- 保持滚动条 -->
<CollectionView.ItemTemplate>
<DataTemplate>
<!-- 这里定义单个卡片的 UI 结构 -->
<Border BackgroundColor="White" Stroke="#CCCCCC"
StrokeThickness="2" Margin="10,0,10,10"
StrokeShape="RoundRectangle 10">
<Grid>
<!-- 定义一行 -->
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" BackgroundColor="#CCCCCC">
<Label Text="{Binding Name}" FontAttributes="Bold"
<Grid>
<!-- 定义一行 -->
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" BackgroundColor="#CCCCCC">
<Label Text="{Binding Name}" FontAttributes="Bold"
FontSize="24" TextColor="Black" Padding="5"/>
</Grid>
<Grid Grid.Row="1">
<VerticalStackLayout>
<Grid>
<HorizontalStackLayout>
<!-- 图片 -->
<Image WidthRequest="100" HeightRequest="100"
Source="{Binding Path=Model, Converter={StaticResource StringToImageConverter}}"/>
<!-- 设备状态 -->
<VerticalStackLayout>
<HorizontalStackLayout>
<Label Text="状态: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding State}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="机台: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding Machine}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</VerticalStackLayout>
</HorizontalStackLayout>
</Grid>
<BoxView HeightRequest="3" Color="#CCCCCC" />
<!-- 设备信息 -->
<Label Text="{Binding ModelA}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelA, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelB}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelB, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelC}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelC, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelD}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelD, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelE}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelE, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelF}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelF, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding Information}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</VerticalStackLayout>
</Grid>
</Grid>
<!-- 点击事件 -->
<Border.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Border.GestureRecognizers>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Grid Grid.Row="1">
<VerticalStackLayout>
<Grid>
<HorizontalStackLayout>
<!-- 图片 -->
<Image WidthRequest="100" HeightRequest="100"
Source="{Binding Path=Model, Converter={StaticResource StringToImageConverter}}"/>
<!-- 设备状态 -->
<VerticalStackLayout>
<HorizontalStackLayout>
<Label Text="状态: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding State}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="机台: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding Machine}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
</VerticalStackLayout>
</HorizontalStackLayout>
</Grid>
<BoxView HeightRequest="3" Color="#CCCCCC" />
<!-- 设备信息 -->
<Label Text="{Binding ModelA}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelA, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelB}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelB, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelC}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelC, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelD}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelD, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelE}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelE, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding ModelF}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=ModelF, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding Information}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</VerticalStackLayout>
</Grid>
</Grid>
<!-- 点击事件 -->
<Border.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Border.GestureRecognizers>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
</ContentPage>
+13 -2
View File
@@ -11,6 +11,7 @@ public partial class InfoPage : ContentPage
{
public static ObservableCollection<InfoItem> InfoItems { get; set; } = new();
private DateTime _lastRefreshTime = DateTime.MinValue;
public static string? DyeMeasurementNumber, ChemicalNumber, PowderNumber, DyeDissolveNumber;
public InfoPage()
{
@@ -44,8 +45,18 @@ public partial class InfoPage : ContentPage
}
};
}
private void HandleUITrigger()
private async void TapGestureRecognizer_ChemicalStatistics(object sender, TappedEventArgs e)
{
await Navigation.PushAsync(new InfoChemicalStatistics());
}
private void HandleUITrigger()
{
_DyeMeasurementNumber.Text = DyeMeasurementNumber;
_ChemicalNumber.Text = ChemicalNumber;
_PowderNumber.Text = PowderNumber;
_DyeDissolveNumber.Text = DyeDissolveNumber;
InfoItems.Clear();
foreach (Dictionary<string, object> List in DataModel.Info_data)
{
@@ -84,7 +95,7 @@ public partial class InfoPage : ContentPage
{
WeakReferenceMessenger.Default.UnregisterAll(this);
}
private async void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e)
{
// 将 sender 强制转换为 BindingContext 定义在 BindableObject
+22 -2
View File
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using TouchSocket.Core;
namespace SunlightAggregationTerminal.Models
{
@@ -11,7 +12,7 @@ namespace SunlightAggregationTerminal.Models
{
public static SqliteHelper sqliteHelper = SQLiteConfig.Config(Path.Combine(FileSystem.AppDataDirectory, "MyAppData.db"))!; //数据库连接路径(获取各平台的应用数据目录)
private Timer timer;
public AppModels()
{
if(sqliteHelper != null)
@@ -40,10 +41,27 @@ namespace SunlightAggregationTerminal.Models
App.GlobalData.LocalAreaNetworkMode = Convert.ToBoolean(dat.Field<object>("LocalAreaNetworkMode"));
App.GlobalData.DarkMode = Convert.ToBoolean(dat.Field<object>("DarkMode"));
App.GlobalData.MessageNotificationMode = Convert.ToBoolean(dat.Field<object>("MessageNotificationMode"));
App.GlobalData.NotificationID = dat.Field<string>("NotificationID")?? "0";
}
}
}
}
}
//启动通知轮询延迟120s启动周期600s
timer = new Timer(TimerNotification, null, TimeSpan.FromSeconds(120), TimeSpan.FromSeconds(120));
}
//轮询通知的定时任务
static void TimerNotification(object? state)
{
if (App.GlobalData.LogNo)//已经登录
{
Dictionary<string, object> NotificationDictionary = new Dictionary<string, object>();
NotificationDictionary.Add("Command", "Notification");
NotificationDictionary.Add("StartTime", App.GlobalData.NotificationID);
NotificationDictionary.Add("EndTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
DataReceived.Transmit(NotificationDictionary.ToJsonString());
}
}
public static void Updata(string sql)
@@ -73,6 +91,8 @@ namespace SunlightAggregationTerminal.Models
{
App.GlobalData.LogNo = false;
// await WebSocketServer.WebSocketClient();
//发送登录请求
if (App.GlobalData.LocalAreaNetworkMode)
{
+3
View File
@@ -37,6 +37,9 @@ namespace SunlightAggregationTerminal.Models
public partial bool DarkMode { get; set; }
[ObservableProperty]
public partial bool MessageNotificationMode { get; set; }
[ObservableProperty]
public partial string NotificationID { get; set; }
public class RefreshUISignal { }
public static List<Dictionary<string, object>> Info_data = new List<Dictionary<string, object>>();
+5 -1
View File
@@ -76,6 +76,10 @@ namespace SunlightAggregationTerminal.Models
public string? DispenseStartTime { get; set; }
public string? DispenseEndTime { get; set; }
public string? DispenseTime { get; set; }
public string? CallTime { get; set; }
public string? UsageTime { get; set; }
public string? Tank { get; set; }
public object? PowderTargetTank { get; set; }
public double? DispenseGrams { get; set; }
public string DispenseGramsDisplay => DispenseGrams?.ToString("F2") ?? "";
public int? DispenseResult { get; set; }
@@ -89,7 +93,7 @@ namespace SunlightAggregationTerminal.Models
public static List<NotificationItem> GetAllItems()
{
DataSet? data = AppModels.Select("select * from Notification Where Time > '" +
DateTime.Now.AddDays(-30).ToString("yyyy-MM-dd HH:mm:ss.fff") + "'");
DateTime.Now.AddDays(-60).ToString("yyyy-MM-dd HH:mm:ss.fff") + "'");
_NotificationData.Clear();
+1 -1
View File
@@ -24,7 +24,7 @@ public partial class MessagePage : ContentPage
MessageItems.Clear();
// 按时间倒序,并只取最新的 50 条
var itemsToShow = allData.OrderByDescending(x => x.Time).Take(50).Where(x => x.Type == MsgType.Message);
var itemsToShow = allData.OrderByDescending(x => x.Time).Take(100).Where(x => x.Type == MsgType.Message);
// 将数据添加到集合中,UI 会自动更新
foreach (var item in itemsToShow)
+1 -1
View File
@@ -25,7 +25,7 @@ public partial class NoticePage : ContentPage
NoticeItems.Clear();
// 按时间倒序,并只取最新的 N 条(例如 50 条)
var itemsToShow = allData.OrderByDescending(x => x.Time).Take(50).Where(x => x.Type == MsgType.Notice);
var itemsToShow = allData.OrderByDescending(x => x.Time).Take(100).Where(x => x.Type == MsgType.Notice);
// 将数据添加到集合中,UI 会自动更新
foreach (var item in itemsToShow)
+1 -1
View File
@@ -24,7 +24,7 @@ public partial class SystemPage : ContentPage
SystemItems.Clear();
// 按时间倒序,并只取最新的 N 条(例如 50 条)
var itemsToShow = allData.OrderByDescending(x => x.Time).Take(50).Where(x => x.Type == MsgType.System);
var itemsToShow = allData.OrderByDescending(x => x.Time).Take(100).Where(x => x.Type == MsgType.System);
// 将数据添加到集合中,UI 会自动更新
foreach (var item in itemsToShow)
+2 -2
View File
@@ -23,8 +23,8 @@
FontAttributes="Bold"
TextColor="Black" />
<HorizontalStackLayout VerticalOptions="Center">
<Label Text="ID:" FontSize="12" TextColor="Gray" Margin="0,0,0,0"/>
<Label Text="{Binding UserId}" FontSize="12" TextColor="Gray" Margin="0,0,0,0"/>
<Label Text="ID:" FontSize="12" TextColor="Gray" Margin="0,0,0,0"/>
<Label Text="{Binding UserId}" FontSize="12" TextColor="Gray" Margin="0,0,0,0"/>
</HorizontalStackLayout>
</VerticalStackLayout>
</HorizontalStackLayout>
+59 -9
View File
@@ -3,17 +3,63 @@ using SunlightAggregationTerminal.Class;
using SunlightAggregationTerminal.Models;
using SunlightAggregationTerminal.View;
using System.Collections.ObjectModel;
using TouchSocket.Core;
namespace SunlightAggregationTerminal;
public partial class ProfilePage : ContentPage
{
private static bool SET = false;
public ProfilePage()
{
InitializeComponent();
this.BindingContext = App.GlobalData;
}
public static void _data(string v,string k)
{
if (k == "Password")
{
App.GlobalData.UserPassword = v;
string sql = @"UPDATE Users SET UserPassword = '" + App.GlobalData.UserPassword
+ "' WHERE User='" + App.GlobalData.User + "';";
AppModels.Updata(sql);
SET = false;
}
if (k == "Name")
{
App.GlobalData.UserName = v;
string sql = @"UPDATE Users SET UserName = '" + App.GlobalData.UserName
+ "' WHERE User='" + App.GlobalData.User + "';";
AppModels.Updata(sql);
SET = false;
}
}
public async void _Command(string dat)
{
DataReceived.Transmit(dat);
SET = true;
// 创建一个 秒的延时任务
Task delayTask = Task.Delay(10000);
// 创建一个监测任务,不断检查变量
Task monitorTask = Task.Run(async () =>
{
while (SET)
{
// 每隔 100 毫秒检查一次,避免 CPU 占用过高
await Task.Delay(1000);
}
});
// 使用 Task.WhenAny 等待任意一个任务完成
Task task = await Task.WhenAny(delayTask, monitorTask);
if (task==delayTask)
{ //超时
await DisplayAlertAsync("", "修改失败", "是");
}
SET = false;
}
private async void Out_Clicked(object sender, EventArgs e)
{
//退出
@@ -38,10 +84,12 @@ public partial class ProfilePage : ContentPage
// 处理结果
if (!string.IsNullOrWhiteSpace(result))
{
App.GlobalData.UserName=result;
string sql = @"UPDATE Users SET UserName = '" + App.GlobalData.UserName
+ "' WHERE User='" + App.GlobalData.User + "';";
AppModels.Updata(sql);
Dictionary<string, object> data_ = new Dictionary<string, object>();
data_.Add("Command", "SETUSER");
data_.Add("USER", App.GlobalData.User);
data_.Add("KEY", "Name");
data_.Add("VALUE", result);
_Command(data_.ToJsonString());
}
}
private async void UserPassword_Tapped(object sender, TappedEventArgs e)
@@ -51,10 +99,12 @@ public partial class ProfilePage : ContentPage
// 处理结果
if (!string.IsNullOrWhiteSpace(result))
{
App.GlobalData.UserPassword = result;
string sql = @"UPDATE Users SET UserPassword = '" + App.GlobalData.UserPassword
+ "' WHERE User='" + App.GlobalData.User + "';";
AppModels.Updata(sql);
Dictionary<string, object> data_ = new Dictionary<string, object>();
data_.Add("Command", "SETUSER");
data_.Add("USER", App.GlobalData.User);
data_.Add("KEY", "Password");
data_.Add("VALUE", result);
_Command(data_.ToJsonString());
}
}
private async void ServerID_Tapped(object sender, TappedEventArgs e)
+26 -2
View File
@@ -2,7 +2,13 @@
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SunlightAggregationTerminal.QueryDetail"
xmlns:converters="clr-namespace:SunlightAggregationTerminal.Converters"
Title="细节" >
<ContentPage.Resources>
<ResourceDictionary>
<converters:StringToBoolConverter x:Key="StringToBoolConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid RowDefinitions="Auto, *" >
<Grid BackgroundColor="#CCCCCC" Padding="10" Grid.Row="0" Grid.Column="0">
<VerticalStackLayout>
@@ -56,9 +62,9 @@
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="开始时间: " FontAttributes="Bold"
<Label Text="呼叫时间: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding DispenseStartTime}" FontAttributes="Bold"
<Label Text="{Binding CallTime}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
@@ -67,6 +73,24 @@
<Label Text="{Binding DispenseEndTime}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="用时: " FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
<Label Text="{Binding UsageTime}" FontAttributes="Bold"
FontSize="22" TextColor="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="目标地址: " FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=Tank, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding Tank}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=Tank, Converter={StaticResource StringToBoolConverter}}"/>
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="溶解流程: " FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=Process, Converter={StaticResource StringToBoolConverter}}"/>
<Label Text="{Binding Process}" FontAttributes="Bold" FontSize="22" TextColor="Black"
IsVisible="{Binding Path=Process, Converter={StaticResource StringToBoolConverter}}"/>
</HorizontalStackLayout>
<BoxView HeightRequest="3" Color="#CCCCCC" />
<HorizontalStackLayout>
<Label Text="{Binding ProductName}" FontAttributes="Bold"
+24 -6
View File
@@ -25,12 +25,13 @@ public partial class QueryDetail : ContentPage
Dictionary<string, object> QueryDictionary = new Dictionary<string, object>();
QueryDictionary.Add("Command", "QueryDetail");
QueryDictionary.Add("Field", "[Dyelot],[ReDye],[StepNumber],[ProductCode],[ProductName]," +
"[ProductType],[Grams],[Created],[DispenseStartTime],[DispenseEndTime],[DispenseTime]," +
"[DispenseGrams],[DispenseResult],[Process],[Notes]");
/* QueryDictionary.Add("Field", "[Dyelot],[ReDye],[StepNumber],[ProductCode],[ProductName]," +
"[ProductType],[Grams],[Created],[DispenseStartTime],[DispenseEndTime],[DispenseTime]," +
"[DispenseGrams],[DispenseResult],[Process]");*/
QueryDictionary.Add("Field", "*");
QueryDictionary.Add("Dyelot", item.Dyelot?.ToString() ?? "");
QueryDictionary.Add("ReDye", item.ReDye?.ToString()??"");
Query_Command(QueryDictionary.ToJsonString());
Query_Command(QueryDictionary.ToJsonString());
}
private void Data_()
@@ -52,7 +53,6 @@ public partial class QueryDetail : ContentPage
$"目标/实际: {list[i].GramsDisplay}g / {list[i].DispenseGramsDisplay}g")
);
// 赋值给最终展示的 ProductName
if (list[0].Process !=null) combinedInfo = combinedInfo + "\n溶解流程:"+ list[0].Process;
firstItem.ProductName = combinedInfo;
return firstItem;
})
@@ -104,6 +104,24 @@ public partial class QueryDetail : ContentPage
//添加入显示信息
foreach (var item in data)
{
//时间处理
if (DateTime.TryParse(item.DispenseEndTime, out DateTime dte))
{
item.DispenseEndTime = dte.ToString("yyyy-MM-dd HH:mm:ss");
if (DateTime.TryParse(item.DispenseStartTime, out DateTime dtr))
{
//计算用时
item.UsageTime = $"{(int)(dte - dtr).TotalMinutes}:{(dte - dtr).Seconds:D2}";
}
}
if (DateTime.TryParse(item.CallTime, out DateTime dtc))
{
item.CallTime = dtc.ToString("yyyy-MM-dd HH:mm:ss");
}
if (item.ProductType == 1 && item.Process == null) item.Process = "未知";
if (item.ProductType == 3) item.Tank = item.PowderTargetTank.ToString();
//行信息
QueryDetailDyelotDetailsItems.Add(item);
}
@@ -113,7 +131,7 @@ public partial class QueryDetail : ContentPage
}
}
}
catch (Exception)
catch (Exception )
{
}
}
+7 -4
View File
@@ -25,12 +25,15 @@
<FileImageSource File="lucidescanline.png" />
</Button.ImageSource>
</Button>
<HorizontalStackLayout Grid.Row="1" Grid.Column="0">
<DatePicker x:Name="StartTime" Format="yyyy年MM月dd日" FontSize="16"/>
<HorizontalStackLayout Grid.Row="1" Grid.Column="0" Margin="5,0,0,0" >
<DatePicker x:Name="StartTime" Format="yyyy年MM月dd日" FontSize="16"
MaximumWidthRequest="150" MinimumWidthRequest="130" WidthRequest="135"/>
<Label Text="~" FontSize="28"/>
<DatePicker x:Name="EndTime" Format="yyyy年MM月dd日" FontSize="16"/>
<DatePicker x:Name="EndTime" Format="yyyy年MM月dd日" FontSize="16"
MaximumWidthRequest="150" MinimumWidthRequest="130" WidthRequest="135"/>
</HorizontalStackLayout>
<Button Grid.Row="1" Grid.Column="1" Text="搜索" Clicked="Button_Clicked" Padding="30,0,30,0" Margin="5" />
<Button Grid.Row="1" Grid.Column="1" Text="搜索" Clicked="Button_Clicked"
WidthRequest="60" Padding="5,0,5,0" Margin="20,0,0,5" />
</Grid>
<Grid Grid.Row="1" Grid.Column="0">
+15 -8
View File
@@ -25,7 +25,7 @@ public partial class QueryPage : ContentPage
QueryDictionary.Add("Command", "QueryDyelot");
QueryDictionary.Add("Field", "[Dyelot],[ReDye],[Program],[Color],[CreationTime]," +
"[Batch],[OrderNo],[TotalWeight],[LiquidRatio],[TotalVolume],[Final],[UserAccount]," +
"[FabricName],[ColorName],[CustomerName],[Notes]");
"[FabricName],[ColorName],[CustomerName]");
QueryDictionary.Add("DyelotName", scannedValue);
Query_Command(QueryDictionary.ToJsonString());
}
@@ -35,12 +35,16 @@ public partial class QueryPage : ContentPage
CardCollectionView.ItemsSource = DyelotItems;
}
//扫码按钮
private async void OnScanButtonClicked(object sender, EventArgs e)
{
ResultEntry.Text = "";
// 跳转到扫码页面
await Navigation.PushAsync(new ScanPage(0));
}
//打开单个选项卡
private async void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e)
{
if (sender is Microsoft.Maui.Controls.BindableObject bindable)
@@ -52,6 +56,7 @@ public partial class QueryPage : ContentPage
await Navigation.PushAsync(new QueryDetail(item));
}
}
ResultEntry.Text = "";
}
//信息回复
@@ -65,6 +70,7 @@ public partial class QueryPage : ContentPage
{
foreach (var item in data)
{
if(item.CreationTime != null) item.CreationTime = item.CreationTime.Replace("T", " ");
DyelotItems.Add(item);
}
@@ -74,7 +80,7 @@ public partial class QueryPage : ContentPage
}
}
}
catch (Exception ex) {
catch (Exception) {
}
}
@@ -104,15 +110,15 @@ public partial class QueryPage : ContentPage
private void Button_Clicked(object sender, EventArgs e)
{
if (ResultEntry.Text != null)
if (ResultEntry.Text.Length >0)
{
Dictionary<string, object> QueryDictionary = new Dictionary<string, object>();
QueryDictionary.Add("Command", "QueryDyelot");
QueryDictionary.Add("Field", "[Dyelot],[ReDye],[Program],[Color],[CreationTime]," +
"[Batch],[OrderNo],[TotalWeight],[LiquidRatio],[TotalVolume],[Final],[UserAccount]," +
"[FabricName],[ColorName],[CustomerName],[Notes]");
"[FabricName],[ColorName],[CustomerName]");
QueryDictionary.Add("DyelotName", ResultEntry.Text);
Query_Command(QueryDictionary.ToJsonString());
Query_Command(QueryDictionary.ToJsonString());
}
else
{
@@ -126,10 +132,11 @@ public partial class QueryPage : ContentPage
QueryDictionary.Add("Command", "Query");
QueryDictionary.Add("Field", "[Dyelot],[ReDye],[Program],[Color],[CreationTime]," +
"[Batch],[OrderNo],[TotalWeight],[LiquidRatio],[TotalVolume],[Final],[UserAccount]," +
"[FabricName],[ColorName],[CustomerName],[Notes]");
QueryDictionary.Add("StartTime", StartTime.Date.ToString()!);
"[FabricName],[ColorName],[CustomerName]");
DateTime StartTimee_ = (DateTime)StartTime.Date!;
QueryDictionary.Add("StartTime", StartTimee_.ToString("yyyy-MM-dd"));
DateTime EndTime_ = (DateTime)EndTime.Date!;
QueryDictionary.Add("EndTime", EndTime_.AddDays(1).ToString());
QueryDictionary.Add("EndTime", EndTime_.AddDays(1).ToString("yyyy-MM-dd"));
Query_Command(QueryDictionary.ToJsonString());
}
+19 -6
View File
@@ -45,10 +45,11 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net10.0-android|AnyCPU'">
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net10.0-android|AnyCPU'">
@@ -91,16 +92,25 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.7" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.7" />
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.51" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.7" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.10" />
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.80" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.10" />
<PackageReference Include="TouchSocket" Version="4.2.10" />
<PackageReference Include="TouchSocket.Http" Version="4.2.10" />
<PackageReference Include="ZXing.Net.Maui.Controls" Version="0.7.4" />
<PackageReference Include="ZXing.Net.Maui.Controls" Version="0.10.3" />
</ItemGroup>
<ItemGroup>
<Compile Update="View\LogLoading.xaml.cs">
<DependentUpon>LogLoading.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<MauiXaml Update="InfoChemicalStatistics.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="InfoDetail.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
@@ -131,6 +141,9 @@
<MauiXaml Update="ScanPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="View\LogLoading.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="View\Loading.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SunlightAggregationTerminal.View.LogLoading"
Title="LogLoading">
<Grid x:Name="LoadingIndicator" BackgroundColor="Gray"
IsVisible="True" Opacity="0.9">
<VerticalStackLayout Padding="30" Spacing="10"
VerticalOptions="Center"
HorizontalOptions="Center">
<Button Text="登 录"
BackgroundColor="#512BD4"
TextColor="White"
HeightRequest="50"
WidthRequest="100"
CornerRadius="10"
Margin="0,10,0,0"
Clicked="Button_Clicked"/>
</VerticalStackLayout>
</Grid>
</ContentPage>
+17
View File
@@ -0,0 +1,17 @@
namespace SunlightAggregationTerminal.View;
public partial class LogLoading : ContentPage
{
public LogLoading()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PopModalAsync();
var logpage = new View.LogPage();
await Navigation.PushModalAsync(logpage);
}
}
+14 -11
View File
@@ -29,7 +29,7 @@ public partial class LogPage : ContentPage
//可用服务器列表
AppModels.sqliteHelper.Open();
var userdata = AppModels.sqliteHelper.ExecuteDataSet("select * from Server", null);
var userdata = AppModels.sqliteHelper.ExecuteDataSet("SELECT * FROM Server", null);
AppModels.sqliteHelper.Close();
Items = new ObservableCollection<ItemOption>();
@@ -40,11 +40,13 @@ public partial class LogPage : ContentPage
{
if (dataRow != null)
{
string _SERVER = dataRow.Field<string>("Server")!;
string _SERVERIP = dataRow.Field<string>("ServerID")! + "," + dataRow.Field<string>("ServerHTTP")!;
var dat = new ItemOption
{
SERVER = dataRow.Field<string>("Server") ?? "",
SERVERIP = dataRow.Field<string>("ServerID") ?? "" +","+
dataRow.Field<string>("ServerHTTP") ?? ""
SERVER = _SERVER,
SERVERIP = _SERVERIP
};
Items.Add(dat);
}
@@ -71,7 +73,7 @@ public partial class LogPage : ContentPage
{
// 跳转到扫码页面
var scanPage = new ScanPage(3);
Navigation.PushAsync(scanPage);
Navigation.PushModalAsync(scanPage);
}
private async void Log_Clicked(object sender, EventArgs e)//登录
@@ -82,9 +84,10 @@ public partial class LogPage : ContentPage
App.GlobalData.ServerID = result[0]?? "";
//判断是否有http连接信息
if (result.Length == 2)
if (result.Length ==2)
{
App.GlobalData.ServerHTTP = result[1] ?? "";
App.GlobalData.LocalAreaNetworkMode = false;
}
else
{
@@ -111,21 +114,21 @@ public partial class LogPage : ContentPage
string sql = @"INSERT INTO Users (User,UserId ,UserName ,UserPassword ,
Enterprise ,Department ,ServerID ,ServerHTTP ,Groups ,
ProxyID ,LogNo ,LocalAreaNetworkMode ,DarkMode ,
MessageNotificationMode ,GUID
MessageNotificationMode ,GUID ,NotificationID
)VALUES('" + UsernameEntry.Text + "','"+ App.GlobalData.UserId +
"','" + App.GlobalData.UserName + "','" + PasswordEntry.Text +
"','"+ App.GlobalData.Enterprise + "','"+ App.GlobalData.Department +
"','" + App.GlobalData.ServerID + "','" +App.GlobalData.ServerHTTP+
"','"+ App.GlobalData.Groups + "'," +
" '',1,0,0,0,'" + Models.AppModels.GetAppUniqueId() + "');";
"','"+ App.GlobalData.Groups + "'," + " '',1,0,0,0,'" +
Models.AppModels.GetAppUniqueId() + "','0');";
AppModels.INSERT(sql);
}
int temp_server = AppModels.Select("SELECT * FROM Server WHERE ServerID='' LIMIT 1;")!.Tables[0].Rows.Count;
int temp_server = AppModels.Select("SELECT * FROM Server WHERE Server='"+ App.GlobalData.Enterprise + "' LIMIT 1;")!.Tables[0].Rows.Count;
if (temp_server == 0)
{
string sql = @"INSERT INTO Server ( Server, ServerID,ServerHTTP)VALUES('" + App.GlobalData.Enterprise + "','" +
App.GlobalData.ServerID+ App.GlobalData.ServerHTTP + "');";
App.GlobalData.ServerID+"','"+ App.GlobalData.ServerHTTP + "');";
AppModels.INSERT(sql);
}
+79
View File
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
元素。
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素,
Windows 将自动选择最兼容的环境。 -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
-->
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>