Compare commits

...
30 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
22 changed files with 317 additions and 125 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();
}
}
}
+7 -1
View File
@@ -102,7 +102,8 @@ namespace SunlightAggregationTerminal.Class
try
{
Person deserializedPerson = JsonSerializer.Deserialize<Person>(dat)!;
var data = JsonSerializer.Deserialize<Dictionary<string, object>>(deserializedPerson.Dat);
var data = JsonSerializer.Deserialize<Dictionary<string, object>>
(AES.AesDecrypt( deserializedPerson.Terminal,deserializedPerson.Dat));
if (data != null)
{
@@ -175,6 +176,7 @@ namespace SunlightAggregationTerminal.Class
&& 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)
@@ -213,6 +215,10 @@ namespace SunlightAggregationTerminal.Class
}
}
}
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)//信息通知接受
{
+35 -38
View File
@@ -95,25 +95,27 @@ namespace SunlightAggregationTerminal.Class
{
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();
}
Dispose();
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();
@@ -124,7 +126,7 @@ namespace SunlightAggregationTerminal.Class
.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))
@@ -137,50 +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
{
//Start();
}
}
//倒计时5秒关闭http客户端
private static Timer? _timer;
private static bool _isDisposed = false;
private static void Start()
{
// 延迟30秒后执行一次,不自动循环
_timer = new Timer(Httpout, null, TimeSpan.FromSeconds(60), Timeout.InfiniteTimeSpan);
}
private static async void Dispose()
{
if (!_isDisposed)
{
_isDisposed = true;
_timer?.Dispose(); // 释放定时器资源
_timer = null;
}
}
private static async void Httpout(object? state)
{
if (httpclient.Online)
{
await httpclient.CloseAsync();
}
Dispose();
}
}
}
+7
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"))
{
@@ -290,6 +296,7 @@ namespace SunlightAggregationTerminal.Class
LocalAreaNetworkMode BOOL DEFAULT (0),
DarkMode BOOL DEFAULT (0),
MessageNotificationMode BOOL DEFAULT (0),
NotificationID TEXT,
GUID TEXT
);";
+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

+13 -2
View File
@@ -4,8 +4,19 @@
x:Class="SunlightAggregationTerminal.InfoChemicalStatistics"
Title="耗用统计">
<Grid>
<Grid>
<CollectionView x:Name="CardCollectionView">
<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>
+17
View File
@@ -22,6 +22,10 @@ public partial class InfoChemicalStatistics : ContentPage
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());
}
@@ -49,6 +53,7 @@ public partial class InfoChemicalStatistics : ContentPage
LoadingIndicator.IsVisible = false;
}
public static void Total_data(string dat)
{
try
@@ -69,4 +74,16 @@ public partial class InfoChemicalStatistics : ContentPage
{
}
}
//搜索按钮
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());
}
}
+63 -50
View File
@@ -2,6 +2,7 @@ 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;
@@ -312,8 +313,8 @@ public class InfoMachineItem
{
ProbuctItem probuctItem = new ProbuctItem();
probuctItem.ProductCode = item.GetValue("ProductCode").ToString()!;
probuctItem.ProductName = item.GetValue("ProductName").ToString()!;
probuctItem.ProductCode = SafeGet(item, "ProductCode");
probuctItem.ProductName = SafeGet(item, "ProductName");
if (item.GetValue("Enabled").ToString()! == "1")
{
probuctItem.ProductState = "启用";
@@ -348,13 +349,13 @@ public class InfoMachineItem
{
foreach (var item in data!)
{
string inf_ = "染机: " + item.GetValue("Machine").ToString()! + "\n";
inf_ = inf_ + "料单: " + item.GetValue("Dyelot").ToString()!;
inf_ = inf_ + "@" + item.GetValue("ReDye").ToString()! + "\n";
inf_ = inf_ + "步骤: " + item.GetValue("StepNumber").ToString()! + "\n";
inf_ = inf_ + "流程: " + item.GetValue("Process").ToString()! + "\n";
inf_ = inf_ + "化料桶: " + item.GetValue("TankNO").ToString()! + "\n";
inf_ = inf_ + "染料桶数: " + item.GetValue("TotalNumber").ToString()!;
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() ?? "";
@@ -367,7 +368,7 @@ public class InfoMachineItem
};
inf_ = inf_ + _Type;
}
inf_ = inf_ + "状态: " + item.GetValue("State").ToString()! + "\n";
inf_ = inf_ + "状态: " + SafeGet(item, "State") + "\n";
InfoMachineItem infoMachineItem = new InfoMachineItem();
infoMachineItem.inf = inf_;
@@ -380,10 +381,10 @@ public class InfoMachineItem
{
foreach (var item in data!)
{
string inf_ = "位置: " + item.GetValue("position").ToString()! + "\n";
inf_ = inf_ + "料单: " + item.GetValue("Dyelot").ToString()!;
inf_ = inf_ + "@" + item.GetValue("ReDye").ToString()! + "\n";
inf_ = inf_ + "步骤: " + item.GetValue("StepNumber").ToString()! + "\n";
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() ?? "";
@@ -406,10 +407,10 @@ public class InfoMachineItem
};
inf_ = inf_ + _BarrelState;
}
inf_ = inf_ + "[" + item.GetValue("Barrelserialnumber").ToString()! + "]\n";
inf_ = inf_ + "上架时间: " + DateTime.Parse(item.GetValue("createtime").ToString() ?? "")
inf_ = inf_ + "[" + SafeGet(item, "Barrelserialnumber") + "]\n";
inf_ = inf_ + "上架时间: " + DateTime.Parse(item.GetValue("Createtime").ToString() ?? "")
.ToString("yyyy-MM-dd HH:mm:ss") + "\n";
inf_ = inf_ + "状态 [" + item.GetValue("State").ToString()! + "]";
inf_ = inf_ + "状态 [" + SafeGet(item, "State") + "]";
InfoMachineItem infoMachineItem = new InfoMachineItem();
infoMachineItem.inf = inf_;
@@ -422,15 +423,15 @@ public class InfoMachineItem
{
foreach (var item in data!)
{
string inf_ = "染机: " + item.GetValue("Machine").ToString()! + "\n";
inf_ = inf_ + "料单: " + item.GetValue("Dyelot").ToString()!;
inf_ = inf_ + "@" + item.GetValue("ReDye").ToString()! + "\n";
inf_ = inf_ + "步骤: " + item.GetValue("StepNumber").ToString()! + "\n";
inf_ = inf_ + "总浴量: " + item.GetValue("Volume").ToString()! + "\n";
inf_ = inf_ + "计量模组: " + item.GetValue("DispenseModule").ToString()! + "\n";
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").ToString()! + "\n";
inf_ = inf_ + "目标位置: " + item.GetValue("TankNo") + "\n";
}
else {
inf_ = inf_ + "目标位置: 未指定\n" ;
@@ -458,7 +459,6 @@ public class InfoMachineItem
{
InfoMachineItems.Add(infoMachineItem);
}
}
if (InfoMachineItems.Count==0) InfoMachineItems.Add(new InfoMachineItem());
}
@@ -468,12 +468,12 @@ public class InfoMachineItem
foreach (var item in data!)
{
DyelotDetailsItem dyelotDetailsItem = new DyelotDetailsItem();
dyelotDetailsItem.Dyelot = item.GetValue("Dyelot").ToString()!;
dyelotDetailsItem.ReDye =int.Parse( item.GetValue("ReDye").ToString()!);
dyelotDetailsItem.StepNumber = int.Parse(item.GetValue("StepNumber").ToString()!);
dyelotDetailsItem.Notes = "染机: " + item.GetValue("Machine").ToString()!+"\n";
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes +
"流程: " + item.GetValue("Process").ToString()!+"\n";
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() ?? "";
@@ -494,8 +494,9 @@ public class InfoMachineItem
{
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + " [" + _TotalNumber+"桶]";
}
dyelotDetailsItem.DispenseStartTime = item.GetValue("DispenseStartTime").ToString()!.Replace("T", " ");
dyelotDetailsItem.DispenseEndTime = item.GetValue("DispenseEndTime").ToString()!.Replace("T", " ");
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))
@@ -513,10 +514,10 @@ public class InfoMachineItem
foreach (var item in data!)
{
DyelotDetailsItem dyelotDetailsItem = new DyelotDetailsItem();
dyelotDetailsItem.Dyelot = item.GetValue("Dyelot").ToString()!;
dyelotDetailsItem.ReDye = int.Parse(item.GetValue("ReDye").ToString()!);
dyelotDetailsItem.StepNumber = int.Parse(item.GetValue("StepNumber").ToString()!);
dyelotDetailsItem.Notes = "位置: " + item.GetValue("Position").ToString()! + "\n";
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() ?? "";
@@ -539,15 +540,16 @@ public class InfoMachineItem
};
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + _BarrelState;
}
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "[" + item.GetValue("Barrelserialnumber").ToString()! + "]\n";
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "[" + SafeGet(item, "Barrelserialnumber") + "]\n";
if (item!.TryGetValue("State", out var _State) && _State != null)
{
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "状态: " + _State;
}
dyelotDetailsItem.DispenseStartTime = "";
dyelotDetailsItem.DispenseStartTime = SafeGet(item, "CreateTime", "T").Replace("T", " ");
dyelotDetailsItem.DispenseEndTime = "";
dyelotDetailsItem.UsageTime = item.GetValue("Createtime").ToString()!.Replace("T", " ");
InfoDyelotHistoryItems.Add(dyelotDetailsItem);
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());
}
@@ -557,10 +559,10 @@ public class InfoMachineItem
foreach (var item in data!)
{
DyelotDetailsItem dyelotDetailsItem = new DyelotDetailsItem();
dyelotDetailsItem.Dyelot = item.GetValue("Dyelot").ToString()!;
dyelotDetailsItem.ReDye = int.Parse(item.GetValue("ReDye").ToString()!);
dyelotDetailsItem.StepNumber = int.Parse(item.GetValue("StepNumber").ToString()!);
dyelotDetailsItem.Notes = "染机: " + item.GetValue("Machine").ToString()! + "\n";
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() ?? "";
@@ -572,9 +574,9 @@ public class InfoMachineItem
_ => "无信息"
};
dyelotDetailsItem.Notes = dyelotDetailsItem.Notes + "状态: " + _State;
}
dyelotDetailsItem.DispenseStartTime = item.GetValue("DispenseStartTime").ToString()!.Replace("T", " ");
dyelotDetailsItem.DispenseEndTime = item.GetValue("DispenseEndTime").ToString()!.Replace("T", " ");
}
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))
@@ -586,8 +588,19 @@ public class InfoMachineItem
}
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;
}
}
}
+3 -6
View File
@@ -13,7 +13,6 @@ namespace SunlightAggregationTerminal.Models
public static SqliteHelper sqliteHelper = SQLiteConfig.Config(Path.Combine(FileSystem.AppDataDirectory, "MyAppData.db"))!; //数据库连接路径(获取各平台的应用数据目录)
private Timer timer;
private static int TimerNotifications = -1440;
public AppModels()
{
if(sqliteHelper != null)
@@ -42,13 +41,14 @@ 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(300));
timer = new Timer(TimerNotification, null, TimeSpan.FromSeconds(120), TimeSpan.FromSeconds(120));
}
//轮询通知的定时任务
@@ -58,10 +58,9 @@ namespace SunlightAggregationTerminal.Models
{
Dictionary<string, object> NotificationDictionary = new Dictionary<string, object>();
NotificationDictionary.Add("Command", "Notification");
NotificationDictionary.Add("StartTime", DateTime.Now.AddMinutes(TimerNotifications).ToString("yyyy-MM-dd HH:mm:ss.fff"));
NotificationDictionary.Add("StartTime", App.GlobalData.NotificationID);
NotificationDictionary.Add("EndTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
DataReceived.Transmit(NotificationDictionary.ToJsonString());
TimerNotifications = -5;
}
}
@@ -134,8 +133,6 @@ namespace SunlightAggregationTerminal.Models
}
}
public static string GetAppUniqueId()
{
const string key = "sunlight_app_unique_id";
+2
View File
@@ -37,6 +37,8 @@ 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 { }
+1 -1
View File
@@ -93,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)
+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">
+13 -7
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 = "";
}
//信息回复
@@ -105,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
{
@@ -127,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());
}
+15 -6
View File
@@ -49,7 +49,7 @@
</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'">
@@ -92,13 +92,19 @@
<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>
@@ -135,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);
}
}
+3 -3
View File
@@ -114,13 +114,13 @@ 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);
}