胶料快检添加离线模式

This commit is contained in:
2026-06-30 11:28:04 +08:00
parent efcd73a565
commit 840e68a450
19 changed files with 1053 additions and 343 deletions

View File

@@ -53,17 +53,13 @@ public class MixingProductionPlanService : IMixingProductionPlanService, ISingle
LoadCacheFromDisk();
_logger.Information($"[密炼计划] 服务初始化,缓存={_localCache.Count},在线={_networkMonitor.IsOnline}");
_networkMonitor.StatusChanged += OnNetworkStatusChanged;
if (_networkMonitor.IsOnline)
_ = Task.Run(() => SyncFromRemoteAsync(CancellationToken.None));
}
private string BaseUrl => (_configuration.GetValue<string>("JeecgIntegration:BaseUrl") ?? "http://localhost:8080/jeecg-boot").TrimEnd('/');
private int DefaultTenantId => (int?)_configuration.GetValue<long?>("JeecgIntegration:DefaultTenantId") ?? 1002;
private HttpClient CreateClient() => _httpClientFactory.CreateClient("JeecgApi");
public async Task<MixingProductionPlanPageResult> PageAsync(
public Task<MixingProductionPlanPageResult> PageAsync(
int pageNo, int pageSize,
DateTime? planDateFrom = null,
DateTime? planDateTo = null,
@@ -73,18 +69,7 @@ public class MixingProductionPlanService : IMixingProductionPlanService, ISingle
string? materialName = null,
CancellationToken ct = default)
{
if (_networkMonitor.IsOnline)
{
try
{
await SyncFromRemoteAsync(ct).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.Warning($"[密炼计划] 列表拉取失败,使用本地缓存:{ex.Message}");
}
}
ct.ThrowIfCancellationRequested();
List<MesXslMixingProductionPlan> source;
lock (_cacheLock)
source = _localCache.Select(Clone).ToList();
@@ -95,25 +80,14 @@ public class MixingProductionPlanService : IMixingProductionPlanService, ISingle
.Skip(Math.Max(0, (pageNo - 1) * pageSize))
.Take(pageSize)
.ToList();
return new MixingProductionPlanPageResult(records, total, pageNo, pageSize);
return Task.FromResult(new MixingProductionPlanPageResult(records, total, pageNo, pageSize));
}
public async Task<List<MesXslMixingProductionPlan>> GetAllCachedAsync(CancellationToken ct = default)
public Task<List<MesXslMixingProductionPlan>> GetAllCachedAsync(CancellationToken ct = default)
{
if (_networkMonitor.IsOnline)
{
try
{
await SyncFromRemoteAsync(ct).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.Warning($"[密炼计划] 全量拉取失败,使用本地缓存:{ex.Message}");
}
}
ct.ThrowIfCancellationRequested();
lock (_cacheLock)
return _localCache.Select(Clone).ToList();
return Task.FromResult(_localCache.Select(Clone).ToList());
}
public async Task<bool> SyncFromRemoteAsync(CancellationToken ct = default)
@@ -190,25 +164,6 @@ public class MixingProductionPlanService : IMixingProductionPlanService, ISingle
}
}
private void OnNetworkStatusChanged(bool isOnline)
{
if (!isOnline) return;
_ = Task.Run(async () =>
{
try
{
if (!await SyncFromRemoteAsync(CancellationToken.None).ConfigureAwait(false))
return;
_eventAggregator.GetEvent<MixingProductionPlanChangedEvent>()
.Publish(new MixingProductionPlanChangedPayload { Action = "reconnect" });
}
catch (Exception ex)
{
_logger.Warning($"[密炼计划] 重连同步失败:{ex.Message}");
}
});
}
private static bool IsPlanContentEqual(MesXslMixingProductionPlan a, MesXslMixingProductionPlan b) =>
string.Equals(GetPlanFingerprint(a), GetPlanFingerprint(b), StringComparison.Ordinal);

View File

@@ -3,33 +3,58 @@ using System.Text.Json;
using YY.Admin.Core;
using YY.Admin.Core.Events;
using YY.Admin.Core.Services;
using YY.Admin.Services.Service;
namespace YY.Admin.Services.Service.MixingProductionPlan;
public class MixingProductionPlanSyncCoordinator : ISingletonDependency
{
private readonly IEventAggregator _eventAggregator;
private readonly IMixingProductionPlanService _planService;
private readonly ILoggerService _logger;
public MixingProductionPlanSyncCoordinator(
IEventAggregator eventAggregator,
SyncPollManager pollManager,
IMixingProductionPlanService planService,
MesQuickTestDataPollManager pollManager,
ILoggerService logger)
{
_eventAggregator = eventAggregator;
_planService = planService;
_logger = logger;
_eventAggregator.GetEvent<RemoteCommandReceivedEvent>()
.Subscribe(OnRemoteCommand, ThreadOption.BackgroundThread);
pollManager.Register("密炼计划", () =>
{
_eventAggregator.GetEvent<MixingProductionPlanChangedEvent>()
.Publish(new MixingProductionPlanChangedPayload { Action = "poll" });
return Task.CompletedTask;
});
_eventAggregator.GetEvent<NetworkStatusChangedEvent>()
.Subscribe(OnNetworkStatusChanged, ThreadOption.BackgroundThread);
pollManager.Register("密炼计划", () => PollSyncAsync("poll"));
_logger.Information("[密炼计划] MixingProductionPlanSyncCoordinator 已启动");
_ = PollSyncAsync("startup");
}
private async Task PollSyncAsync(string action)
{
try
{
if (!await _planService.SyncFromRemoteAsync(CancellationToken.None).ConfigureAwait(false))
return;
_eventAggregator.GetEvent<MixingProductionPlanChangedEvent>()
.Publish(new MixingProductionPlanChangedPayload { Action = action });
}
catch (Exception ex)
{
_logger.Warning($"[密炼计划] 轮询同步失败:{ex.Message}");
}
}
private void OnNetworkStatusChanged(NetworkStatusChangedPayload payload)
{
if (!payload.IsOnline) return;
_ = Task.Run(() => PollSyncAsync("reconnect"));
}
private void OnRemoteCommand(RemoteCommandPayload payload)
@@ -53,7 +78,18 @@ public class MixingProductionPlanSyncCoordinator : ISingletonDependency
MixingProductionPlanId = idEl.ValueKind == JsonValueKind.String ? idEl.GetString() : null
};
_logger.Information($"[密炼计划] STOMP action={changed.Action}, id={changed.MixingProductionPlanId}");
_eventAggregator.GetEvent<MixingProductionPlanChangedEvent>().Publish(changed);
_ = Task.Run(async () =>
{
try
{
if (await _planService.SyncFromRemoteAsync(CancellationToken.None).ConfigureAwait(false))
_eventAggregator.GetEvent<MixingProductionPlanChangedEvent>().Publish(changed);
}
catch (Exception ex)
{
_logger.Warning($"[密炼计划] STOMP 同步失败:{ex.Message}");
}
});
}
catch (Exception ex)
{