using System; using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp.BackgroundWorkers; using Volo.Abp.Threading; using Volo.Abp.Uow; using Win_in.Sfs.Wms.DataExchange.Domain; using Win_in.Sfs.Wms.DataExchange.Domain.Shared; using Win_in.Sfs.Wms.DataExchange.Iac.QadAgent.PostServices; using Win_in.Sfs.Wms.DataExchange.Wms; namespace Win_in.Sfs.Wms.DataExchange.Iac.QadAgent.Outgoing; public class OutgoingFromWmsWorker : AsyncPeriodicBackgroundWorkerBase { private readonly OutgoingOptions _options; private readonly IPostService _postService; public OutgoingFromWmsWorker( AbpAsyncTimer timer, IOptions options, IServiceScopeFactory serviceScopeFactory, IPostService postService ) : base(timer, serviceScopeFactory) { _options = options.Value.OutgoingOptions; _postService = postService; Timer.Period = options.Value.OutgoingOptions.PeriodSeconds * 1000; //default 5 minutes } [UnitOfWork] protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) { Logger.LogInformation("Starting: Handling Outgoing Exchange data..."); if (!_options.Active) { Logger.LogInformation("Outgoing Exchange is not active!"); return; } //Resolve dependencies var outgoingDataManager = workerContext .ServiceProvider .GetRequiredService(); //Do the work var batchSize = _options.BatchSize; var retryTimes = _options.RetryTimes; var outgoingDataList = await outgoingDataManager.GetToBeProcessedListAsync(batchSize, retryTimes).ConfigureAwait(false); Logger.LogInformation($"{outgoingDataList.Count} Outgoing Exchange records were Found"); foreach (var outgoingData in outgoingDataList) { try { //定时主动推送数据到外部系统 await PostToOtherSystemAsync(outgoingData).ConfigureAwait(false); //归档并删除 await outgoingDataManager.FileAndDeleteAsync(outgoingData).ConfigureAwait(false); } catch (Exception e) { Logger.LogException(e); e = e.GetBaseException(); outgoingData.SetError(EnumExchangeDataErrorCode.Exception, e.Message); await outgoingDataManager.UpdateAsync(outgoingData).ConfigureAwait(false); } } Logger.LogInformation("Completed: Handling Outgoing Exchange data..."); } protected virtual async Task PostToOtherSystemAsync(OutgoingFromWms outgoingOuterData) { if (Enum.TryParse(outgoingOuterData.DataType, true, out EnumOutgoingDataType dataType)) { var baseUrl = _options.BaseUrl; var apiUrl = GetApiUrl(dataType, _options); var dataContent = outgoingOuterData.DataContent; if (!TryDeserialize(dataType, dataContent)) { outgoingOuterData.SetError(EnumExchangeDataErrorCode.WrongDataFormat, dataType.ToString()); } if (GetApiEnabled(dataType, _options)) { var username = _options.Username; var password = _options.Password; await _postService.PostAsync(baseUrl, apiUrl, dataContent, username, password).ConfigureAwait(false); } outgoingOuterData.SetSuccess(); } else { outgoingOuterData.SetError(EnumExchangeDataErrorCode.UnknownDataType, "UnknownDataType"); } } private static bool TryDeserialize(EnumOutgoingDataType dataType, string dataContent) { try { switch (dataType) { case EnumOutgoingDataType.PurchaseReceipt: var tryReceipt = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.PurchaseReturn: var tryReturn = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.Transfer: var tryTransfer = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.BackFlush: var tryBackFlush = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.Rework: var tryRework = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.PreShipper: var tryPreShipper = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.Count: var tryCount = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.UnplannedReceipt: var tryUnplannedReceipt = JsonSerializer.Deserialize(dataContent); break; case EnumOutgoingDataType.UnplannedDeliver: var tryUnplannedDeliver = JsonSerializer.Deserialize(dataContent); break; default: throw new ArgumentOutOfRangeException(nameof(dataType), dataType, null); } } catch (Exception) { return false; } return true; } private static string GetApiUrl(EnumOutgoingDataType dataType, OutgoingOptions options) { var apiUrl = dataType switch { EnumOutgoingDataType.PurchaseReceipt => options.Apis.Receipt.Url,//采购收货 EnumOutgoingDataType.PurchaseReturn => options.Apis.Return.Url,//采购退货 EnumOutgoingDataType.Transfer => options.Apis.Transfer.Url,//库存转移 EnumOutgoingDataType.BackFlush => options.Apis.BackFlush.Url, //生产回冲 EnumOutgoingDataType.Rework => options.Apis.Rework.Url, //返修 EnumOutgoingDataType.PreShipper => options.Apis.PreShipper.Url, //预发运 EnumOutgoingDataType.UnplannedReceipt => options.Apis.UnplannedReceipt.Url, //计划外入库 EnumOutgoingDataType.UnplannedDeliver => options.Apis.UnplannedDeliver.Url, //计划外出库 EnumOutgoingDataType.Count => options.Apis.Count.Url, //盘点 _ => throw new ArgumentOutOfRangeException(nameof(dataType), dataType, null) }; return apiUrl; } private static bool GetApiEnabled(EnumOutgoingDataType dataType, OutgoingOptions options) { var apiEnabled = dataType switch { EnumOutgoingDataType.PurchaseReceipt => options.Apis.Receipt.Enabled,//采购收货 EnumOutgoingDataType.PurchaseReturn => options.Apis.Return.Enabled,//采购退货 EnumOutgoingDataType.Transfer => options.Apis.Transfer.Enabled,//库存转移 EnumOutgoingDataType.BackFlush => options.Apis.BackFlush.Enabled, //生产回冲 EnumOutgoingDataType.Rework => options.Apis.Rework.Enabled, //返修 EnumOutgoingDataType.PreShipper => options.Apis.PreShipper.Enabled, //预发运 EnumOutgoingDataType.UnplannedReceipt => options.Apis.UnplannedReceipt.Enabled, //计划外入库 EnumOutgoingDataType.UnplannedDeliver => options.Apis.UnplannedDeliver.Enabled, //计划外出库 EnumOutgoingDataType.Count => options.Apis.Count.Enabled, //盘点 _ => throw new ArgumentOutOfRangeException(nameof(dataType), dataType, null) }; return apiEnabled; } }