using Mapster; using Masuit.Tools; using SixLabors.Fonts.Tables.AdvancedTypographic; using SqlSugar; using System; using System.Text.RegularExpressions; using System.Threading.Tasks; using WIDESEA_Cache; using WIDESEA_Core.Const; using WIDESEA_DTO.Location; using WIDESEA_DTO.WMS; using WIDESEA_IServices; using WIDESEA_Model.Models; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_QuartzJob.Models; namespace WIDESEA_StorageTaskServices; public partial class Dt_TaskService : ServiceBase, IDt_TaskService { private readonly LogFactory LogFactory = new LogFactory(); private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IStockInfoRepository _stockInfoRepository; private readonly IStockInfoDetailRepository _stockInfoDetailRepository; private readonly IDt_Task_HtyRepository _task_HtyRepository; private readonly IMapper _mapper; private readonly ILocationInfoRepository _locationRepository; private readonly ITaskExecuteDetailRepository _taskExecuteDetailRepository; private readonly ILocationStatusChangeRecordRepository _locationStatusChangeRecordRepository; private readonly IBoxingInfoRepository _boxingInfoRepository; //组盘 private readonly IDt_AreaInfoRepository _areaInfoRepository; //区域 private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly ISys_ConfigService _configService; public Dt_TaskService(IDt_TaskRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoRepository stockInfoRepository, IDt_Task_HtyRepository task_HtyRepository, IMapper mapper, ILocationInfoRepository locationRepository, ITaskExecuteDetailRepository taskExecuteDetailRepository, ILocationStatusChangeRecordRepository locationStatusChangeRecordRepository, IBoxingInfoRepository boxingInfoRepository, IDt_AreaInfoRepository areaInfoRepository, IStockInfoDetailRepository stockInfoDetailRepository, IDt_StationManagerRepository stationManagerRepository, ISys_ConfigService configService) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _stockInfoRepository = stockInfoRepository; _task_HtyRepository = task_HtyRepository; _mapper = mapper; _locationRepository = locationRepository; _taskExecuteDetailRepository = taskExecuteDetailRepository; _locationStatusChangeRecordRepository = locationStatusChangeRecordRepository; _boxingInfoRepository = boxingInfoRepository; _areaInfoRepository = areaInfoRepository; _stockInfoDetailRepository = stockInfoDetailRepository; _stationManagerRepository = stationManagerRepository; _configService = configService; } #region 外部接口方法 #region 出库任务完成 public async Task CompleteOutboundTaskAsync(Dt_Task task, DtStockInfo stock) { WebResponseContent content = new WebResponseContent(); try { task.TaskState = (int)TaskOutStatusEnum.OutFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; await _unitOfWorkManage.UseTranAsync(async () => { await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); }); } catch (Exception ex) { return content.Error(ex.Message); } return content; } #endregion 出库任务完成 #region 移库任务完成 /// /// 移库任务完成 /// /// 任务数据合集 /// 返回结果集 public async Task CompleteTransferTaskAsync(Dt_Task task, DtStockInfo stock) { WebResponseContent content = new WebResponseContent(); try { // 更新货位和库存信息 (DtStockInfo updateStock, DtLocationInfo locationInForm, DtLocationInfo locationInfoTo) = UpdateStockLocation(stock, task); var taskHty = CreateHistoricalTask(task); LogFactory.GetLog("任务完成").InfoFormat(true, "移库任务完成", $"货位地址:{task.TargetAddress},修改后库存数据:{JsonConvert.SerializeObject(updateStock)},原先货位数据:{locationInForm}"); // 执行数据库事务 bool isResult = false; if (isResult) content.OK("移库任务完成成功"); else content.Error("移库任务完成失败"); } catch (Exception err) { Console.WriteLine(err.Message.ToString()); } return content; } #endregion 移库任务完成 #region 入库任务完成 /// /// 完成入库任务 /// /// 任务数据合集 /// 返回结果集 public async Task CompleteInboundTaskAsync(Dt_Task task) { WebResponseContent content = new WebResponseContent(); try { task.TaskState = (int)TaskInStatusEnum.InFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; await _unitOfWorkManage.UseTranAsync(async () => { await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); }); } catch (Exception ex) { return content.Error(ex.Message); } return content; } #endregion 入库任务完成 #region AGV搬运任务完成 public async Task CompleteCarryTaskAsync(Dt_Task task,DtStockInfo stockInfo) { WebResponseContent content = new WebResponseContent(); try { task.TaskState = (int)TaskAGVCarryStatusEnum.CarryFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; await _unitOfWorkManage.UseTranAsync(async () => { await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); }); } catch (Exception ex) { return content.Error(ex.Message); } return content; } #endregion #region AGV跨楼层任务完成 public async Task CompleteAcrossFloorTaskAsync(Dt_Task task, DtStockInfo stockInfo) { WebResponseContent content = new WebResponseContent(); try { task.TaskState = (int)TaskAcrossFloorStatusEnum.CarryFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; await _unitOfWorkManage.UseTranAsync(async () => { await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); }); } catch (Exception ex) { return content.Error(ex.Message); } return content; } #endregion #region 任务完成 /// /// 完成任务 /// /// 任务编号 /// 返回结果集 public async Task CompleteAsync(int taskNum) { // 初始化响应内容 WebResponseContent content = new WebResponseContent(); // 提取任务数据 LogFactory.GetLog("任务完成").InfoFormat(true, "提取任务数据", $"任务号:{taskNum}"); // 验证任务是否存在 var task = await GetByTaskNum(taskNum); if (task == null) { return content.Error("任务不存在"); } LogFactory.GetLog("任务完成").InfoFormat(true, "验证任务是否存在", JsonConvert.SerializeObject(task)); // 验证库存是否存在 var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { return await CompleteOutboundTaskAsync(task, stock); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { return await CompleteInboundTaskAsync(task); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) { return await CompleteTransferTaskAsync(task, stock); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.CarryGroup) { return await CompleteCarryTaskAsync(task, stock); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.AcrossFloorGroup) { return await CompleteAcrossFloorTaskAsync(task, stock); } else { return content.Error("未找到任务类型"); } } #endregion 任务完成 #region 请求任务入库 public async Task RequestTaskAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = await GetByTaskAddress(taskDto.Position, taskDto.TargetAddress); if (task != null) { return content.Error("起点或终点存在任务"); } var station = _stationManagerRepository.QueryFirst(x => x.stationType == 1 && x.Roadway == "SC1"); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "SC1", TargetAddress = taskDto.TargetAddress, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = station.stationChildCode, OrderNo = null, PalletCode = taskDto.PalletCode, SourceAddress = taskDto.Position, CurrentAddress = taskDto.Position, TaskState = (int)TaskInStatusEnum.InNew, TaskType = (int)TaskInboundTypeEnum.Inbound, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = "1F", }; var taskDTO = CreateListTaskDTO(taskNew); return content = await SendWCSTask(taskDTO); } catch (Exception err) { content.Error(err.Message); } return content; } /// /// 更新任务货位 /// /// /// public async Task UpdateExistingTask(RequestTaskDto input) { WebResponseContent content = new WebResponseContent(); try { var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == input.PalletCode); if (task == null) return content.Error($"暂未找到【{input.PalletCode}】的任务"); return content = await UpdateExistingTask(input, task); } catch (Exception err) { return content.Error(err.Message); } } #endregion 请求任务入库 #region 请求出库 /// /// 请求托盘任务 /// /// 目标位置 /// 托盘类型(1:实盘,2:空盘) /// 区域编码 /// 巷道编码集合 /// 返回结果集 public async Task RequestOutTaskAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = await GetByTaskAddress(taskDto.Position, taskDto.TargetAddress); if (task != null) { return content.Error("起点或终点存在任务"); } var station = _stationManagerRepository.QueryFirst(x => x.stationType == 1 && x.Roadway == "SC1"); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "SC1", TargetAddress = taskDto.TargetAddress, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = station.stationChildCode, OrderNo = null, PalletCode = taskDto.PalletCode, SourceAddress = taskDto.Position, CurrentAddress = taskDto.Position, TaskState = (int)TaskOutStatusEnum.OutNew, TaskType = (int)TaskOutboundTypeEnum.Outbound, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = "1F", }; var taskDTO = CreateListTaskDTO(taskNew); return content = await SendWCSTask(taskDTO); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion 请求出库(实盘&空盘) #region 请求跨楼层2任务 /// /// 请求跨楼层2任务 /// /// /// public async Task AcrossFloorTaskAsync(RequestAcrossFloorTaskDto taskDto) { WebResponseContent content=new WebResponseContent(); try { var task = BaseDal.QueryFirst(x => x.TaskNum == Convert.ToInt32(taskDto.TaskNum) && x.PalletCode == taskDto.PalletCode); if(task == null) return content.Error("未找到任务"); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "AGV", TargetAddress = task.TargetAddress, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = taskDto.NextAddress, OrderNo = null, PalletCode = task.PalletCode, SourceAddress = taskDto.NextAddress, CurrentAddress = taskDto.NextAddress, TaskState = (int)TaskAcrossFloorStatusEnum.SecondCarry, TaskType = (int)TaskAcrossFloorTypeEnum.AcrossFloorCarry, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = "", }; var taskDTO = CreateTaskDTO(taskNew); var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; await _unitOfWorkManage.UseTranAsync(async () => { await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); }); return content.OK(data: taskDTO); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 请求跨楼层任务 public async Task RequestAcrossFloorTaskAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = await GetByTaskAddress(taskDto.Position, taskDto.TargetAddress); if (task != null) { return content.Error("起点或终点存在任务"); } var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == taskDto.Position); if (station != null) { var next = _stationManagerRepository.QueryFirst(x => x.stationType == 5 && x.stationFloor == station.stationFloor); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "AGV", TargetAddress = taskDto.TargetAddress, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = next.stationChildCode, OrderNo = null, PalletCode = taskDto.PalletCode, SourceAddress = taskDto.Position, CurrentAddress = taskDto.Position, TaskState = (int)TaskAcrossFloorStatusEnum.CarryNew, TaskType = (int)TaskAcrossFloorTypeEnum.AcrossFloorCarry, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = station.stationFloor, }; var taskDTO = CreateListTaskDTO(taskNew); return content = await SendWCSTask(taskDTO); } return content.Error("未找到提升机站点"); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 请求AGV搬运任务 public async Task RequestAGVCarryTaskAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = await GetByTaskAddress(taskDto.Position,taskDto.TargetAddress); if (task != null) { return content.Error("起点或终点存在任务"); } var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == taskDto.Position); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "AGV", TargetAddress = taskDto.TargetAddress, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = taskDto.TargetAddress, OrderNo = null, PalletCode = taskDto.PalletCode, SourceAddress = taskDto.Position, CurrentAddress = taskDto.Position, TaskState = (int)TaskAGVCarryStatusEnum.CarryNew, TaskType = (int)TaskAGVCarryTypeEnum.Carry, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = station.stationFloor, }; var taskDTO = CreateListTaskDTO(taskNew); return content = await SendWCSTask(taskDTO); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 任务状态更改 /// /// 更新任务状态&出库解盘 /// /// /// /// public async Task UpdateTaskStatus(int taskNum, int taskState) { WebResponseContent content = new WebResponseContent(); try { var task = await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum); if (task == null) return content.Error("未找到任务"); if (taskState == (int)TaskOutStatusEnum.Line_OutFinish || taskState == (int)TaskInStatusEnum.SC_InFinish) { var taskHty = CreateHistoricalTask(task); await _unitOfWorkManage.UseTranAsync(async () => { var asb = await BaseDal.DeleteDataByIdAsync(task.TaskId); var asbHty = await _task_HtyRepository.AddDataAsync(taskHty) > 0; if (asb && asbHty) content.OK(); else throw new Exception(); }); content.OK(); } else { task.TaskState = taskState; var asb = await BaseDal.UpdateDataAsync(task); if (asb) content.OK(); else content.Error(); } } catch (Exception ex) { content.Error(ex.Message); } return content; } #endregion 任务状态更改 #region 获取AGV任务号 private static readonly Random _random = new Random(); public static string GenerateUniqueId() { // 获取当前毫秒级时间戳 long timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // 生成4位随机数(0000-9999) int randomNumber = _random.Next(0, 10000); string randomPart = randomNumber.ToString("D4"); // 补零到4位 return $"{timestamp}{randomPart}"; } #endregion #endregion 外部接口方法 #region 调用WCS接口 private string GetAGVIPAddress(string baseIp, string name) { var configz = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wcsBasez = configz.Where(x => x.ConfigKey == baseIp).FirstOrDefault()?.ConfigValue; var address = configz.Where(x => x.ConfigKey == name).FirstOrDefault()?.ConfigValue; if (wcsBasez == null || address == null) { throw new InvalidOperationException("WMS IP 未配置"); } return wcsBasez + address; } public async Task SendWCSTask(List taskDTO) { WebResponseContent content = new WebResponseContent(); var AgvSendTaskAddrss = GetAGVIPAddress(SysConfigConst.WCSIPAddress, SysConfigConst.ReceiveTask); // 发送请求并等待响应 var result = await HttpHelper.PostAsync(AgvSendTaskAddrss, taskDTO.ToJsonString()); content = JsonConvert.DeserializeObject(result.ToString()); return content; } #endregion #region 内部调用方法 /// /// 创建任务DTO /// private List CreateListTaskDTO(Dt_Task task) { return new List { new WMSTaskDTO { TaskNum = task.TaskNum.Value, Grade = task.Grade.Value, PalletCode = task.PalletCode, RoadWay = task.Roadway, SourceAddress = task.SourceAddress, TargetAddress = task.TargetAddress, TaskState = task.TaskState.Value, Id = 0, TaskType = task.TaskType, AGVTaskNum = task.AGVTaskNum, } }; } private WMSTaskDTO CreateTaskDTO(Dt_Task task) { return new WMSTaskDTO { TaskNum = task.TaskNum.Value, Grade = task.Grade.Value, PalletCode = task.PalletCode, RoadWay = task.Roadway, SourceAddress = task.SourceAddress, TargetAddress = task.TargetAddress, TaskState = task.TaskState.Value, Id = 0, TaskType = task.TaskType, AGVTaskNum = task.AGVTaskNum, }; } private async Task DeleteStockInfoAsync(int stockId) { var isStockUpdated = await _stockInfoRepository.DeleteDataByIdAsync(stockId); if (!isStockUpdated) { throw new Exception("库存信息更新失败"); } } private async Task AddStockInfoHtyAsync(DtStockInfo_Hty dtStock) { var isStockAdd = await SqlSugarHelper.DbWMS.InsertNav(dtStock).IncludesAllFirstLayer().ExecuteCommandAsync(); if (!isStockAdd) { throw new Exception("库存历史信息添加失败"); } } private async Task UpdateLocationAsync(DtLocationInfo info) { var isStockUpdated = await _locationRepository.UpdateDataAsync(info); if (!isStockUpdated) { throw new Exception("库位信息更新失败"); } } private async Task DeleteStockInfoDetailsAsync(IEnumerable details) { var ids = details.Select(x => (object)x.Id).ToArray(); var isStockDetailUpdated = await _stockInfoDetailRepository.DeleteDataByIdsAsync(ids); if (!isStockDetailUpdated) { throw new Exception("库存详情信息更新失败"); } } private async Task DeleteTaskAsync(int taskId) { var isTaskUpdated = await BaseDal.DeleteDataByIdAsync(taskId); if (!isTaskUpdated) { throw new Exception("任务信息更新失败"); } } private async Task AddTaskHtyAsync(Dt_Task_Hty taskHty) { var isTaskAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0; if (!isTaskAdd) { throw new Exception("历史任务信息添加失败"); } } public override WebResponseContent DeleteData(object[] key) { WebResponseContent content = new WebResponseContent(); // 创建历史任务实例模型 try { foreach (var item in key) { Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == Convert.ToInt32(key)); if (task == null) { return content.Error("未找到任务信息!"); } var taskHtyNG = CreateHistoricalTask(task, true); // 添加历史任务 var isTaskHtyAdd = _task_HtyRepository.AddData(taskHtyNG) > 0; // 删除任务数据 var isTaskDelete = BaseDal.Delete(task.TaskId); } return content.OK("删除成功!"); } catch (Exception ex) { return content.Error("删除任务异常:" + ex.Message); } } /// /// 根据任务号获取任务 /// /// /// public async Task GetByTaskNum(int taskNum) { return await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum); } public async Task GetByTaskAddress(string SourceAddress, string TargetAddress) { return await BaseDal.QueryFirstAsync(x => x.SourceAddress == SourceAddress|| x.TargetAddress== TargetAddress); } #endregion 内部调用方法 #region private 内部方法 /// /// 创建历史任务记录 /// /// /// private Dt_Task_Hty CreateHistoricalTask(Dt_Task task, bool isHand = false) { // 更新任务状态 task.TaskState = task.TaskType > 199 ? (int)TaskInStatusEnum.InFinish : (int)TaskOutStatusEnum.OutFinish; task.CurrentAddress = task.NextAddress; // 创建历史任务 var taskHty = _mapper.Map(task); taskHty.FinishTime = DateTime.Now; taskHty.TaskId = 0; taskHty.OperateType = isHand ? (int)OperateTypeEnum.人工删除 : App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.SourceId = task.TaskId; if (isHand) { taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; } return taskHty; } /// /// 更新库存位置 /// /// 库存对象 /// 目标位置 // 更新库存和位置信息 private (DtStockInfo, DtLocationInfo, DtLocationInfo) UpdateStockLocation(DtStockInfo stock, Dt_Task task) { //修改来源库位和 目标库位状态 var fromLocation = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway); fromLocation.LocationStatus = LocationEnum.Free.ObjToInt(); var toLocation = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway); toLocation.LocationStatus = LocationEnum.InStock.ObjToInt(); // 将库存位置设置为目标位置 stock.LocationCode = task.TargetAddress; // 返回更新后的库存和位置信息 return (stock, fromLocation, toLocation); } #region 任务请求方法 private static readonly SemaphoreSlim _semaphoreUpdate = new SemaphoreSlim(1, 1); // 更新任务货位 private async Task UpdateExistingTask(RequestTaskDto input, Dt_Task task) { await _semaphoreUpdate.WaitAsync(); try { if (task == null) { return new WebResponseContent().Error("任务对象为空"); } try { // 创建WebResponseContent对象 var content = new WebResponseContent(); var location = await GetEmptyLocation(task.Roadway); if (location == null) { return content.Error("无法获取货位信息"); } string toAddress = location.LocationCode; int taskState = (int)TaskInStatusEnum.Line_InFinish; int beforeStatus = location.LocationStatus; // 更新货位信息 location.LocationStatus = (int)LocationEnum.Lock; // 更新任务信息 MapTaskProperties(task, input, toAddress, taskState); // 开始事务 var isResult = await UpdateTaskAsync(task, location, beforeStatus); if (!isResult) { _unitOfWorkManage.RollbackTran(); return content.Error("更新任务失败"); } // 提交事务 _unitOfWorkManage.CommitTran(); return content.OK(data: task); } catch (Exception ex) { // 回滚事务 _unitOfWorkManage.RollbackTran(); // 这里可以添加日志记录 return new WebResponseContent().Error($"更新任务时发生错误: {ex.Message}"); } } catch (Exception) { throw; } finally { _semaphoreUpdate.Release(); } } private void MapTaskProperties(Dt_Task task, RequestTaskDto input, string toAddress, int taskState) { task.CurrentAddress = input.Position; task.TargetAddress = toAddress; task.NextAddress = toAddress; task.TaskState = taskState; } // 修改任务 private async Task UpdateTaskAsync(Dt_Task task, DtLocationInfo location, int beforeStatus) { bool isResult = await BaseDal.UpdateDataAsync(task); bool isTaskDetail = await _taskExecuteDetailRepository.AddDetailAsync(task, false, TaskDescription.GetTaskUpdateDescription(task.PalletCode, task.CurrentAddress, task.TargetAddress, TaskInStatusEnum.Line_InFinish.GetIntegralRuleTypeEnumDesc())); LocationChangeRecordDto changeRecordDto = new LocationChangeRecordDto() { AfterStatus = location.LocationStatus, BeforeStatus = beforeStatus, TaskNum = task.TaskNum.Value, LocationId = location.Id, LocationCode = location.LocationCode, ChangeType = (int)StatusChangeTypeEnum.AutomaticStorage, }; bool isUpdateChange = _locationStatusChangeRecordRepository.AddStatusChangeRecord(changeRecordDto); bool isUpdateLo = await _locationRepository.UpdateDataAsync(location); return isResult && isUpdateLo && isTaskDetail; } /// /// 获取货位号 /// /// public async Task GetEmptyLocation(string roadWay) { try { List LocationInfoList = await _locationRepository.QueryDataAsync(x => x.RoadwayNo == roadWay && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == EnableEnum.Enable.ObjToInt()); List LocationInfoResult = new List(); foreach (DtLocationInfo item in LocationInfoList) { DtLocationInfo locationItem = new DtLocationInfo(); if (item.Depth == 2) { locationItem = _locationRepository.QueryFirst(x => x.Column == item.Column && x.RoadwayNo == item.RoadwayNo && x.Layer == item.Layer && x.Depth != item.Depth && x.Row != item.Row && (SqlFunc.Abs(x.Row - item.Row) == 1) && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == EnableEnum.Enable.ObjToInt()); if (locationItem != null) { LocationInfoResult.Add(item); } } else { locationItem = _locationRepository.QueryFirst(x => x.Column == item.Column && x.RoadwayNo == item.RoadwayNo && x.Layer == item.Layer && x.Depth != item.Depth && x.Row != item.Row && (SqlFunc.Abs(x.Row - item.Row) == 1) && x.LocationStatus == (int)LocationEnum.InStock && x.EnalbeStatus == EnableEnum.Enable.ObjToInt()); if (locationItem != null) { LocationInfoResult.Add(item); } } } if (LocationInfoResult.Count < 2) { throw new Exception("当前空闲货位不足!"); } return LocationInfoResult.OrderByDescending(x => x.Depth).ThenBy(x => x.Column).ThenBy(x => x.Layer).FirstOrDefault(); } catch (Exception ex) { throw new Exception(ex.Message); } } #endregion 任务请求方法 #endregion private 内部方法 }