using AutoMapper; using Kean.Application.Command.Interfaces; using Kean.Application.Command.ViewModels; using Kean.Domain.Stock.Commands; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Orleans; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; namespace Kean.Application.Command.Implements { /// <summary> /// 库存命令服务实现 /// </summary> public class StockService : IStockService { private readonly ILogger<StockService> _logger; // 日志 //private readonly ICommandBus _bus; // 命令总线 //private readonly INotification _notifications; // 总线通知 private readonly IMapper _mapper; // 模型映射 private readonly IClusterClient _cluster; // 筒仓客户端 /// <summary> /// 依赖注入 /// </summary> public StockService( ILogger<StockService> logger, //ICommandBus bus, //INotification notifications, IMapper mapper, IClusterClient cluster) { _logger = logger; //_bus = bus; //_notifications = notifications; _mapper = mapper; _cluster = cluster; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.Inbound 方法 */ public async Task<Failure> Inbound(Stock stock, bool? full, int? destination) { var stopwatch = new Stopwatch(); var command = _mapper.Map<InboundCommand>(stock); command.Destination = destination; command.Full = full; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:入库:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).Inbound(command); // if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.Outbound 方法 */ public async Task<Failure> Outbound(Stock stock) { var stopwatch = new Stopwatch(); var command = _mapper.Map<OutboundCommand>(stock); var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:出库:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).Outbound(command); // if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.Update 方法 */ public async Task<Failure> Update(Stock stock) { var stopwatch = new Stopwatch(); var command = _mapper.Map<UpdateCommand>(stock); command.Transaction = "Update"; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:更新:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).Update(command); // if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.Combine 方法 */ public async Task<Failure> Combine(Stock stock, bool? full, int? destination) { var stopwatch = new Stopwatch(); var command = _mapper.Map<CombineCommand>(stock); command.Destination = destination; command.Full = full; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:合并:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).Combine(command); // if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.Inventory 方法 */ public async Task<Failure> Inventory(Stock stock) { var stopwatch = new Stopwatch(); var command = _mapper.Map<InventoryCommand>(stock); var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:盘点:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).Inventory(command); // if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /////////////////////////////////////////// /* * 实现 Kean.Application.Command.Interfaces.IStockService.ScanInbound 方法 */ public async Task<(string Device, Failure Failure)> ScanInbound(Stock stock, bool? full, int? destination) { var stopwatch = new Stopwatch(); var command = _mapper.Map<ScanInboundCommand>(stock); command.Destination = destination; command.Full = full; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:扫描入库:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).ScanInbound(command); // if (result.Failure != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.PalletIn 方法 */ public async Task<Failure> PalletIn(Stock stock, bool? full, int? destination) { var stopwatch = new Stopwatch(); var command = _mapper.Map<PalletInCommand>(stock); command.Destination = destination; command.Full = full; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:托盘入库:条码[{Barcode}],标签[{Tag}]。", hash, stock.Barcode, stock.Tag); stopwatch.Start(); //await _bus.Execute(command); //var result = _notifications.FirstOrDefault(); var result = await _cluster.GetGrain<IAggregateGrain>(Guid.Empty).PalletIn(command); // if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。", hash, stopwatch.ElapsedMilliseconds); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.AgvApplyIn 方法 */ public async Task<(string Device, Failure Failure)> AgvApplyIn( string requestNo, string barcode, string postUser, string targetNo, IEnumerable<Batch> batchs) { (string Device, Failure Failure) result; Failure failure = new Failure(); result.Failure = failure; result.Device = string.Empty; var stopwatch = new Stopwatch(); var grain = _cluster.GetGrain<IAggregateGrain>(Guid.Empty); PreScanInboundCommand command = new PreScanInboundCommand(); command.RequestNo = requestNo; command.Barcode = barcode; //@=@ W1固定值 300000-数据接收缓存区 command.Source = "300000"; command.Postuser = postUser; command.Operator = -4; command.Batchs = _mapper.Map<IEnumerable<Kean.Domain.Stock.Models.Batch>>(batchs); //输送 if (!targetNo.Equals("ASRS")) { string transaction = "bypass"; int bypassArea = 0; //@=@ W1固定值 targetNo转换bypassArea switch (targetNo) { case "L1-1": bypassArea = 150001; break; case "L1-2": bypassArea = 150002; break; case "L2-1": bypassArea = 160001; break; case "L2-2": bypassArea = 160002; break; case "L3-1": bypassArea = 170001; break; case "L3-2": bypassArea = 170002; break; case "L4-1": bypassArea = 250001; break; case "L4-2": bypassArea = 250002; break; case "L5-1": bypassArea = 260001; break; case "L5-2": bypassArea = 260002; break; case "L6-1": bypassArea = 270001; break; case "L6-2": bypassArea = 270002; break; case "BException": bypassArea = 120000; break; case "AException": bypassArea = 220000; break; default: result.Failure.ErrorMessage = $"目标地址({targetNo})不正确,请检查"; return result; } command.Tag = JsonConvert.SerializeObject(new { Transaction = transaction, postUser = postUser, BypassArea = bypassArea }); } var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:AgvApplyIn参数-{1}]。", hash, JsonConvert.SerializeObject(new { requestNo = requestNo, barcode = barcode, postUser = postUser, targetNo = targetNo, batchs = batchs })); stopwatch.Start(); result = await grain.PreScanInbound(command); if (result.Failure != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。结果{Failure}", hash, stopwatch.ElapsedMilliseconds, result); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.SetRollResult 方法 */ public async Task<Failure> SetRollResult( string batchNo, string code, string message, int @operator) { var stopwatch = new Stopwatch(); var grain = _cluster.GetGrain<IAggregateGrain>(Guid.Empty); SetRollResultCommand command = new SetRollResultCommand(); command.BatchNo = batchNo; command.Code = code; command.Message = message; command.Operator = @operator; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:SetRollResult参数-{1}]。", hash, JsonConvert.SerializeObject(new { batchNo = batchNo, code = code, message = message, @operator = @operator })); stopwatch.Start(); var result = await grain.SetRollResult(command); _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。结果{Failure}", hash, stopwatch.ElapsedMilliseconds, result); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.ScanInbound 方法 */ public async Task<(string Device, Failure Failure)> ApplyIn(Stock stock, bool? full, int? destination) { var stopwatch = new Stopwatch(); var grain = _cluster.GetGrain<IAggregateGrain>(Guid.Empty); PreScanInboundCommand command = new PreScanInboundCommand(); //command.RequestNo = requestNo; command.Barcode = stock.Barcode; command.Sfc = stock.Lines.Select(r=>r.Bill ).ToArray(); //@=@ 固定值 string source = "110000"; if (stock.Barcode.StartsWith("M2A")) { source = "210000"; } if (stock.Barcode.StartsWith("W1JPA")) { source = "210000"; } command.Source = source; command.Postuser = stock.Lines.First().Postuser; command.Operator = stock.Operator; command.Remark = stock.Lines.First().Remark; command.Qc = stock.Lines.First().QualityState; command.Tag = stock.Tag; command.AgvApplyInFlag = false; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:ApplyIn参数-{1}]。", hash, JsonConvert.SerializeObject(new { barcode = command.Barcode, sfc = command.Sfc, slSource = command.Source, @operator = command.Operator })); stopwatch.Start(); var result = await grain.PreScanInbound(command); _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。结果{Failure}", hash, stopwatch.ElapsedMilliseconds, result); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.FreezeThaw 方法 */ public async Task<(int barcodeCount, Failure Failure)> SetQcStatus(int @operator, string operation, int? code, string batch, DateTime? mfgFrom, DateTime? mfgTo, DateTime? inboundTimeFrom, DateTime? inboundTimeTo, string barcode, string supplier, string[] barcodes) { var stopwatch = new Stopwatch(); var grain = _cluster.GetGrain<IAggregateGrain>(Guid.Empty); PreSetQcStatusCommand command = new PreSetQcStatusCommand(); command.Enable = operation.Equals("freeze") ? false : true; command.Operator = @operator; command.GoodsCode = code; command.Batch = batch; command.ManufacturingDateFrom = mfgFrom; command.ManufacturingDateTo = mfgTo; command.InboundTimeFrom = inboundTimeFrom; command.InboundTimeTo = inboundTimeTo; command.Barcode = barcode; command.Supplier = supplier; command.Operator = @operator; command.BarcodeList = barcodes; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:SetQcStatus参数-{1}]。", hash, JsonConvert.SerializeObject(new { @operator = @operator, operation = operation, code = code, batch = batch, mfgFrom = mfgFrom, mfgTo = mfgTo, inboundTimeFrom = inboundTimeFrom, inboundTimeTo = inboundTimeTo, barcode = barcode, supplier = supplier })); stopwatch.Start(); var result = await grain.PreSetQcStatus(command); if (result.Failure != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。结果{Failure}", hash, stopwatch.ElapsedMilliseconds, result); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.ChangeStorageProperty 方法 */ public async Task<Failure> ChangeStorageProperty( string requestNo, Batch batch, string freezenStatus) { Failure result = new Failure(); var stopwatch = new Stopwatch(); var grain = _cluster.GetGrain<IAggregateGrain>(Guid.Empty); ChangeStoragePropertyCommand command = new ChangeStoragePropertyCommand(); command.RequestNo = requestNo; command.Serialno = batch.serialno; command.FreezenStatus = freezenStatus; command.Batch = _mapper.Map<Kean.Domain.Stock.Models.Batch>(batch); var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:ChangeStorageProperty-{1}]。", hash, JsonConvert.SerializeObject(new { requestNo = requestNo, freezenStatus = freezenStatus, batch = JsonConvert.SerializeObject(batch) })); stopwatch.Start(); result = await grain.ChangeStorageProperty(command); if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。结果{Failure}", hash, stopwatch.ElapsedMilliseconds, result); return result; } /* * 实现 Kean.Application.Command.Interfaces.IStockService.BatchReFeedback 方法 */ public async Task<Failure> BatchReFeedback(int[] id) { Failure result = new Failure(); var stopwatch = new Stopwatch(); var grain = _cluster.GetGrain<IAggregateGrain>(Guid.Empty); BatchReFeedbackCommand command = new BatchReFeedbackCommand(); command.idList = id; var hash = command.GetHashCode(); _logger.LogInformation("过程[{Hash}]开始:BatchReFeedback-{1}]。", hash, JsonConvert.SerializeObject(new { idList = string.Join(",", id) })); stopwatch.Start(); result = await grain.BatchReFeedback(command); if (result != null) { _logger.LogWarning("过程[{Hash}]中断:{Failure}。", hash, result); } _logger.LogInformation("过程[{Hash}]结束:耗时{TimeSpan}ms。结果{Failure}", hash, stopwatch.ElapsedMilliseconds, result); return result; } } }