桌面端新增密炼计划获取

This commit is contained in:
2026-06-17 17:52:31 +08:00
parent 816af5df6e
commit 372dc10be2
23 changed files with 1335 additions and 92 deletions

View File

@@ -8,6 +8,7 @@ using System.Web;
using YY.Admin.Core;
using YY.Admin.Core.Entity;
using YY.Admin.Core.Events;
using YY.Admin.Core.Helper;
using YY.Admin.Core.Services;
namespace YY.Admin.Services.Service.RubberQuickTestStd;
@@ -115,7 +116,7 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
var entity = resultEl.Deserialize<MesXslRubberQuickTestStd>(_jsonOpts);
if (entity != null)
{
UpsertLocalCacheMain(entity);
UpsertIfChanged(entity);
return CloneMain(entity);
}
}
@@ -134,14 +135,14 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
}
}
public async Task SyncFromRemoteAsync(CancellationToken ct = default)
public async Task<bool> SyncFromRemoteAsync(CancellationToken ct = default)
{
await _syncLock.WaitAsync(ct).ConfigureAwait(false);
try
{
if (!_networkMonitor.IsOnline)
return;
return false;
var query = HttpUtility.ParseQueryString(string.Empty);
query["pageNo"] = "1";
@@ -158,16 +159,37 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
var records = doc.RootElement.GetProperty("result").GetProperty("records")
.Deserialize<List<MesXslRubberQuickTestStd>>(_jsonOpts) ?? new();
List<MesXslRubberQuickTestStd> localSnapshot;
lock (_cacheLock)
localSnapshot = _localCache.Select(CloneMain).ToList();
var (merged, stats) = MesReadOnlyCacheMergeHelper.Merge(
localSnapshot,
records,
x => x.Id,
IsStdListContentEqual,
CloneMain,
MergeStdUpdated);
if (!stats.HasChanges)
{
_logger.Information($"[快检实验标准] 与 MES 对比无差异,跳过更新 count={merged.Count}");
return false;
}
lock (_cacheLock)
{
_localCache = records.Select(CloneMain).ToList();
_localCache = merged;
SaveCacheToDiskUnsafe();
}
_logger.Information($"[快检实验标准] 同步完成 count={records.Count}");
_logger.Information(
$"[快检实验标准] 差异同步完成 total={merged.Count} 新增={stats.Added} 变更={stats.Updated} 删除={stats.Removed}");
return true;
}
catch (Exception ex)
{
_logger.Warning($"[快检实验标准] 远程同步失败:{ex.Message}");
return false;
}
finally
{
@@ -180,7 +202,8 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
if (!isOnline) return;
_ = Task.Run(async () =>
{
await SyncFromRemoteAsync(CancellationToken.None).ConfigureAwait(false);
if (!await SyncFromRemoteAsync(CancellationToken.None).ConfigureAwait(false))
return;
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
.Publish(new RubberQuickTestStdChangedPayload { Action = "reconnect" });
});
@@ -202,19 +225,67 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
return q.OrderByDescending(x => x.CreateTime ?? DateTime.MinValue).ToList();
}
private void UpsertLocalCacheMain(MesXslRubberQuickTestStd entity)
private bool UpsertIfChanged(MesXslRubberQuickTestStd entity)
{
if (string.IsNullOrWhiteSpace(entity.Id)) return;
if (string.IsNullOrWhiteSpace(entity.Id)) return false;
lock (_cacheLock)
{
var idx = _localCache.FindIndex(x => string.Equals(x.Id, entity.Id, StringComparison.OrdinalIgnoreCase));
var copy = CloneMain(entity);
if (idx >= 0) _localCache[idx] = copy;
else _localCache.Insert(0, copy);
if (idx >= 0)
{
if (IsStdDetailContentEqual(_localCache[idx], entity))
return false;
_localCache[idx] = CloneMain(entity);
}
else
{
_localCache.Insert(0, CloneMain(entity));
}
SaveCacheToDiskUnsafe();
return true;
}
}
private static bool IsStdListContentEqual(MesXslRubberQuickTestStd a, MesXslRubberQuickTestStd b) =>
string.Equals(GetStdListFingerprint(a), GetStdListFingerprint(b), StringComparison.Ordinal);
private static bool IsStdDetailContentEqual(MesXslRubberQuickTestStd a, MesXslRubberQuickTestStd b) =>
string.Equals(GetStdDetailFingerprint(a), GetStdDetailFingerprint(b), StringComparison.Ordinal);
private static string GetStdListFingerprint(MesXslRubberQuickTestStd x)
{
var snap = CloneMain(x);
snap.LineList = null;
return JsonSerializer.Serialize(snap, _jsonOpts);
}
private static string GetStdDetailFingerprint(MesXslRubberQuickTestStd x) =>
JsonSerializer.Serialize(CloneMain(x), _jsonOpts);
private static MesXslRubberQuickTestStd MergeStdUpdated(MesXslRubberQuickTestStd local, MesXslRubberQuickTestStd remote)
{
var copy = CloneMain(remote);
if ((copy.LineList == null || copy.LineList.Count == 0) && local.LineList is { Count: > 0 })
{
copy.LineList = local.LineList.Select(l => new MesXslRubberQuickTestStdLine
{
Id = l.Id,
StdId = l.StdId,
DataPointId = l.DataPointId,
PointName = l.PointName,
LowerLimit = l.LowerLimit,
UpperLimit = l.UpperLimit,
LowerWarn = l.LowerWarn,
UpperWarn = l.UpperWarn,
TargetValue = l.TargetValue,
SortNo = l.SortNo
}).ToList();
}
return copy;
}
private void UpsertLocalCacheMain(MesXslRubberQuickTestStd entity) => UpsertIfChanged(entity);
private void LoadCacheFromDisk()
{
try

View File

@@ -2,7 +2,6 @@ using Prism.Events;
using System.Text.Json;
using YY.Admin.Core;
using YY.Admin.Core.Events;
using YY.Admin.Core.Events;
namespace YY.Admin.Services.Service.RubberQuickTestStd;
@@ -21,8 +20,6 @@ public class RubberQuickTestStdSyncCoordinator : ISingletonDependency
_eventAggregator.GetEvent<RemoteCommandReceivedEvent>()
.Subscribe(OnRemoteCommand, ThreadOption.BackgroundThread);
_eventAggregator.GetEvent<NetworkStatusChangedEvent>()
.Subscribe(OnNetworkStatusChanged, ThreadOption.BackgroundThread);
pollManager.Register("胶料快检实验标准", () =>
{
@@ -34,14 +31,6 @@ public class RubberQuickTestStdSyncCoordinator : ISingletonDependency
_logger.Information("[快检实验标准] RubberQuickTestStdSyncCoordinator 已启动");
}
private void OnNetworkStatusChanged(NetworkStatusChangedPayload payload)
{
if (!payload.IsOnline) return;
_logger.Information("[快检实验标准] 网络恢复,触发补偿刷新");
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
.Publish(new RubberQuickTestStdChangedPayload { Action = "reconnect" });
}
private void OnRemoteCommand(RemoteCommandPayload payload)
{
try