using Mapster; using MapsterMapper; using Microsoft.Extensions.Configuration; using SqlSugar; using System.DirectoryServices.Protocols; using System.Text.Json; using WIDESEA_Common.Constants; using WIDESEA_Common.LocationEnum; using WIDESEA_Common.StockEnum; using WIDESEA_Common.TaskEnum; using WIDESEA_Common.WareHouseEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Core; using WIDESEA_Core.Enums; using WIDESEA_Core.Helper; using WIDESEA_DTO.GradingMachine; using WIDESEA_DTO.MES; using WIDESEA_DTO.Stock; using WIDESEA_DTO.Task; using WIDESEA_IBasicService; using WIDESEA_IRecordService; using WIDESEA_IStockService; using WIDESEA_ITaskInfoService; using WIDESEA_Model.Models; namespace WIDESEA_TaskInfoService { public partial class TaskService : ServiceBase>, ITaskService { private readonly IMapper _mapper; private readonly IStockInfoService _stockInfoService; private readonly ILocationInfoService _locationInfoService; private readonly HttpClientHelper _httpClientHelper; private readonly IConfiguration _configuration; private readonly RoundRobinService _roundRobinService; private readonly IMesService _mesService; private readonly ITask_HtyService _task_HtyService; private readonly IStockInfo_HtyService _stockInfo_HtyService; private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IRecordService _recordService; public IRepository Repository => BaseDal; private readonly Dictionary _taskOrderBy = new() { { nameof(Dt_Task.Grade), OrderByType.Desc }, { nameof(Dt_Task.CreateDate), OrderByType.Asc }, }; public List TaskTypes => typeof(TaskTypeEnum).GetEnumIndexList(); public List TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList(); public TaskService( IRepository BaseDal, IMapper mapper, IStockInfoService stockInfoService, ILocationInfoService locationInfoService, HttpClientHelper httpClientHelper, IConfiguration configuration, RoundRobinService roundRobinService, IMesService mesService, ITask_HtyService task_HtyService, IStockInfo_HtyService stockInfo_HtyService, IUnitOfWorkManage unitOfWorkManage, IRecordService recordService) : base(BaseDal) { _mapper = mapper; _stockInfoService = stockInfoService; _locationInfoService = locationInfoService; _httpClientHelper = httpClientHelper; _configuration = configuration; _roundRobinService = roundRobinService; _mesService = mesService; _task_HtyService = task_HtyService; _stockInfo_HtyService = stockInfo_HtyService; _unitOfWorkManage = unitOfWorkManage; _recordService = recordService; } /// /// 查找托盘是否存在未完成任务。 /// private async Task GetTaskByPalletCodeAsync(string palletCode) { try { var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == palletCode); if (task == null) return WebResponseContent.Instance.Error("未找到对应的任务"); var taskDto = _mapper.Map(task); return WebResponseContent.Instance.OK("查询成功", taskDto); } catch (Exception ex) { return WebResponseContent.Instance.Error($"查询任务失败: {ex.Message}"); } } /// /// 保存任务历史。 /// private async Task SaveTaskHistoryAsync(Dt_Task task, string operateType) { var historyTask = _mapper.Map(task); historyTask.InsertTime = DateTime.Now; historyTask.OperateType = operateType; var saved = await _task_HtyService.Repository.AddDataAsync(historyTask) > 0; return saved ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error("任务历史保存失败"); } /// /// 保存库存历史。 /// private async Task SaveStockHistoryAsync(Dt_StockInfo stockInfo, string operateType) { var historyStock = _mapper.Map(stockInfo); historyStock.InsertTime = DateTime.Now; historyStock.OperateType = operateType; var saved = await _stockInfo_HtyService.Repository.AddDataAsync(historyStock) > 0; return saved ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error("库存历史保存失败"); } /// /// 完成任务后统一处理。 /// private async Task CompleteTaskAsync(Dt_Task task, string operateType = "") { var deleteTaskResult = await BaseDal.DeleteDataAsync(task); if (!deleteTaskResult) return WebResponseContent.Instance.Error("任务完成失败"); return await SaveTaskHistoryAsync(task, operateType); } /// /// 根据巷道确定目标地址,支持多出库口轮询。 /// private string DetermineTargetAddress(string roadway, Dictionary> addressMap) { if (string.IsNullOrWhiteSpace(roadway)) return TaskAddressConstants.DEFAULT_ADDRESS; string? matchedPrefix = null; foreach (var kvp in addressMap) { if (roadway.Contains(kvp.Key)) { matchedPrefix = kvp.Key; break; } } if (matchedPrefix == null) return TaskAddressConstants.DEFAULT_ADDRESS; if (!addressMap.TryGetValue(matchedPrefix, out var addresses) || addresses == null || addresses.Count == 0) return TaskAddressConstants.DEFAULT_ADDRESS; if (addresses.Count == 1) return addresses[0]; return _roundRobinService.GetNextAddress(matchedPrefix, addresses); } /// /// 根据库存 Remark 确定目标地址(GW_1→[11001,11010]轮询,GW_2→CWSC1,CW_1→22001)。 /// private string DetermineTargetAddressByRemark(string remark, string roadway, Dictionary> addressMap) { // 根据 Remark 确定目标地址 if (!string.IsNullOrWhiteSpace(remark)) { return remark switch { StockRemarkConstants.GW1 => _roundRobinService.GetNextAddress(StockRemarkConstants.GW1, TaskAddressConstants.GW1_ADDRESSES.ToList()), StockRemarkConstants.GW2 => TaskAddressConstants.GW2_ADDRESS, StockRemarkConstants.CW1 => TaskAddressConstants.CW1_ADDRESS, _ => DetermineTargetAddress(roadway, addressMap) }; } // Remark 为空时,回退到巷道配置 return DetermineTargetAddress(roadway, addressMap); } } }