刘磊
5 天以前 5eeed44ad21748ed7560a8c688d4e2d2f03555c8
ÏîÄ¿´úÂë/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -5,10 +5,12 @@
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WIDESEA_Comm.WCSInterface.Requst;
using WIDESEA_Core.Const;
using WIDESEA_DTO.WMS;
using WIDESEA_IServices;
using WIDESEA_IStoragIntegrationServices;
using WIDESEA_StoragIntegrationServices;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob.Models;
@@ -28,19 +30,21 @@
    private readonly IDt_StationManagerRepository _stationManagerRepository;
    private readonly ISys_ConfigService _configService;
    private readonly IDt_PalletStockInfoRepository _palletStockInfoRepository;
    private readonly IDt_PalletStockInfoDetailRepository _palletStockInfoDetailRepository;
    private readonly IDt_PalletStockInfo_htyRepository _palletStockInfo_HtyRepository;
    private readonly IBoxingInfoRepository _boxingInfoRepository;
    public static string AGV_Interface = "http://192.168.1.195:10200/";
    public Dt_TaskService(IDt_TaskRepository BaseDal,
                                IUnitOfWorkManage unitOfWorkManage,
                                IDt_OutOrderRepository outOrderRepository,
                                IStockInfoRepository stockInfoRepository,
                                IDt_Task_HtyRepository task_HtyRepository,
                                IMapper mapper,
                                ILocationInfoRepository locationRepository,
                                ITaskExecuteDetailRepository taskExecuteDetailRepository,
                                ILocationStatusChangeRecordRepository locationStatusChangeRecordRepository,
                                IStockInfoDetailRepository stockInfoDetailRepository,
                                IDt_StationManagerRepository stationManagerRepository,
                                ISys_ConfigService configService, IDt_PalletStockInfoRepository palletStockInfoRepository) : base(BaseDal)
                                ISys_ConfigService configService, IDt_PalletStockInfoRepository palletStockInfoRepository, IDt_PalletStockInfo_htyRepository palletStockInfo_HtyRepository, IBoxingInfoRepository boxingInfoRepository, IDt_PalletStockInfoDetailRepository palletStockInfoDetailRepository) : base(BaseDal)
    {
        _unitOfWorkManage = unitOfWorkManage;
@@ -52,12 +56,14 @@
        _stationManagerRepository = stationManagerRepository;
        _configService = configService;
        _palletStockInfoRepository = palletStockInfoRepository;
        _palletStockInfo_HtyRepository = palletStockInfo_HtyRepository;
        _boxingInfoRepository = boxingInfoRepository;
        _palletStockInfoDetailRepository = palletStockInfoDetailRepository;
    }
    #region å¤–部接口方法
    #region å…¥åº“任务完成
    /// <summary>
    /// å®Œæˆå…¥åº“任务
    /// </summary>
@@ -70,8 +76,7 @@
        try
        {
            // èŽ·å–MES信息和目标位置信息
            //var mes_Wheels = await _InWheels_MesRepository.QueryFirstNavAsync(x => x.Wheels_Num == task.PalletCode);
            // èŽ·å–åº“ä½ä¿¡æ¯
            var locationInf = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.TargetAddress && x.RoadwayNo == task.Roadway);
            int lastStatus = locationInf.LocationStatus;
@@ -81,14 +86,24 @@
            // åˆ›å»ºåŽ†å²ä»»åŠ¡å®žä¾‹æ¨¡åž‹
            var taskHty = CreateHistoricalTask(task);
            //获取组盘信息
            var boxinginfo = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
            // æ ¹æ®åˆ›å»ºåº“存实例模型
            var boxDetail = boxinginfo.BoxingInfoDetails.Adapt<List<Dt_PalletStockInfoDetail>>();
            Dt_PalletStockInfo palletStockInfo = new Dt_PalletStockInfo
            {
                CreateDate = DateTime.Now,
                Creater = task.Creater,
                LocationCode = task.TargetAddress,
                StockStatus = 2,
                PalletCode = task.PalletCode,
                AreaCode = task.Roadway,
                StockInfoDetails = boxDetail
            };
            // æ‰§è¡Œæ•°æ®åº“事务
            bool isResult = await ExecuteTransaction(palletStockInfo, taskHty, locationInf, task.TaskId);
            bool isResult = await ExecuteTransaction(palletStockInfo, taskHty, locationInf, task.TaskId, boxinginfo);
            if (isResult)
            {
                _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(locationInf, lastStatus, (int)StatusChangeTypeEnum.AutomaticStorage, task.TaskNum);
@@ -111,28 +126,42 @@
    #endregion å…¥åº“任务完成
    #region å‡ºåº“任务完成
    public async Task<WebResponseContent> CompleteStackTaskAsync(Dt_Task task, Dt_PalletStockInfo stock)
    public async Task<WebResponseContent> CompleteStackTaskAsync(Dt_Task task)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            // æ›´æ–°åº“位状态与任务状态
            //(var loc, var tas) = UpdateStockAndTaskStatus(stock, task);
            //var taskHty = task.Adapt<Dt_Task_Hty>();
            //taskHty.FinishTime = DateTime.Now;
            //taskHty.OperateType = (int)OperateTypeEnum.自动完成;
            var stock = _palletStockInfoRepository.QueryFirst(x => x.PalletCode == task.PalletCode);
            //Dt_WheelsStock_hty stockInfo_Hty = stock.Adapt<Dt_WheelsStock_hty>();
            //stockInfo_Hty.FinishWheelDate = DateTime.Now;
            //stockInfo_Hty.OperateType = (int)OperateTypeEnum.自动完成;
            (var loc, var tas) = UpdateStockAndTaskStatus(stock, task);
            var taskHty = task.Adapt<Dt_Task_Hty>();
            taskHty.FinishTime = DateTime.Now;
            taskHty.OperateType = (int)OperateTypeEnum.自动完成;
            //// äº‹åŠ¡å¤„ç†
            //await _unitOfWorkManage.UseTranAsync(async () =>
            //{
            //    var isLocationUpdate = await _locationRepository.UpdateDataAsync(loc);                      //更新库位
            //    //var isTaskUpdated = await BaseDal.DeleteDataByIdAsync(task.TaskId);                         //删除任务
            //    var isTaskAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0;                        //加入历史任务
            //});
            Dt_PalletStockInfo_hty stockInfo_Hty = stock.Adapt<Dt_PalletStockInfo_hty>();
            stockInfo_Hty.FinishTime = DateTime.Now;
            stockInfo_Hty.OperateType = (int)OperateTypeEnum.自动完成;
            var boxinfo = _boxingInfoRepository.QueryFirst(x => x.PalletCode == task.PalletCode);
            // äº‹åŠ¡å¤„ç†
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                var isLocationUpdate = await _locationRepository.UpdateDataAsync(loc);                      //更新库位
                var isPalletHty = await _palletStockInfo_HtyRepository.AddDataAsync(stockInfo_Hty);         //添加历史库存记录
                var isTaskUpdated = await BaseDal.DeleteDataByIdAsync(task.TaskId);                         //删除任务
                var isTaskAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0;                        //加入历史任务
                var isDelete = await _palletStockInfoRepository.DeleteDataAsync(stock);                     //删除库存
                await DeleteStockInfoDetailsAsync(stock.StockInfoDetails);                                  //删除库存明细
                //if (boxinfo != null)
                //{
                //    var isDeleteBoxing = await _boxingInfoRepository.Db.DeleteNav<DtBoxingInfo>(x => x.Id == boxinfo.Id)
                //                         .Include(x => x.BoxingInfoDetails)
                //                         .ExecuteCommandAsync();                                           //删除组盘
                //}
            });
            return content.OK("任务完成成功", task.Remark);
        }
@@ -143,7 +172,7 @@
        }
    }
    private (DtLocationInfo, Dt_Task) UpdateStockAndTaskStatus(Dt_WheelsStock stock, Dt_Task task)
    private (DtLocationInfo, Dt_Task) UpdateStockAndTaskStatus(Dt_PalletStockInfo stock, Dt_Task task)
    {
        var location = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway);
        int lastStatus = location.LocationStatus;
@@ -184,22 +213,18 @@
        // éªŒè¯åº“存是否存在
        var stock = await _palletStockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
        //var stock = await _palletStockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
        // æ ¹æ®ä»»åŠ¡ç±»åž‹è°ƒç”¨ç›¸åº”çš„å®Œæˆä»»åŠ¡æ–¹æ³•
        switch (task.TaskType)
        {
            case (int)TaskInboundTypeEnum.Inbound:
            case (int)TaskInboundTypeEnum.InWheels:
            case (int)TaskInboundTypeEnum.InBrake:
                LogFactory.GetLog("任务完成").InfoFormat(true, "入库任务", "");
                return await CompleteInboundTaskAsync(task);
            case (int)TaskOutboundTypeEnum.Outbound:
            case (int)TaskOutboundTypeEnum.OutBrake:
            case (int)TaskOutboundTypeEnum.OutWheels:
                LogFactory.GetLog("任务完成").InfoFormat(true, "出库任务", "");
                return await CompleteStackTaskAsync(task, stock);
                return await CompleteStackTaskAsync(task);
            default:
                return content.Error("任务类型不存在");
        }
@@ -208,11 +233,6 @@
    #endregion ä»»åŠ¡å®Œæˆ
    #region è¯·æ±‚任务入库
    #region
    #endregion è¯·æ±‚任务入库
    /// <summary>
    /// æ›´æ–°ä»»åŠ¡è´§ä½
    /// </summary>
@@ -227,7 +247,7 @@
            if (task == null)
                return content.Error($"暂未找到【{input.PalletCode}】的任务");
            return content = await UpdateExistingTask(input, task);
            return content; //= await UpdateExistingTask(input, task);
        }
        catch (Exception err)
        {
@@ -237,29 +257,6 @@
    #endregion å¤–部接口方法
    #region è¯·æ±‚出库(实盘)
    /// <summary>
    /// åˆ›å»ºä»»åŠ¡DTO
    /// </summary>
    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
        };
    }
    #endregion è¯·æ±‚出库(实盘&空盘)
    #region ä»»åŠ¡çŠ¶æ€æ›´æ”¹
@@ -328,9 +325,9 @@
                return content.Error("未查询到对应的库存信息");
            }
            if (stockInfo.StockStatus != 1) return content.Error("指定失败:当前状态不允许指定出库");
            if (stockInfo.StockStatus != 2) return content.Error("指定失败:当前状态不允许指定出库");
            stockInfo.StockStatus = 4;
            stockInfo.StockStatus = 3;
            //查询库位是否锁定,
            var location = _locationRepository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode);
@@ -344,67 +341,80 @@
            {
                return content.Error($"【{palletCode}】已存在任务");
            }
            // var stationInfo = _stationManagerRepository.QueryFirst(x => x.stationChildCode == station);
            var stationInfo = _stationManagerRepository.QueryFirst(x => x.stationChildCode == station);
            // åˆ›å»ºå¹¶æ·»åŠ ä»»åŠ¡åˆ°æ•°æ®åº“
            string agvId = Guid.NewGuid().ToString().Replace("-", "").Take(16);
            task = new Dt_Task
            {
                Grade = 1,
                Roadway = "SC1",
                TargetAddress = station,
                Roadway = stationInfo.Roadway,
                TargetAddress = stationInfo.stationLocation,
                Dispatchertime = DateTime.Now,
                MaterialNo = "",
                NextAddress = "2010",
                NextAddress = stationInfo.stationLocation,
                OrderNo = null,
                PalletCode = stockInfo.PalletCode,
                SourceAddress = stockInfo.LocationCode,
                CurrentAddress = stockInfo.LocationCode,
                TaskState = (int)TaskOutStatusEnum.OutNew,
                TaskType = (int)TaskOutboundTypeEnum.OutWheels,
                TaskType = (int)TaskOutboundTypeEnum.Outbound,
                TaskNum = BaseDal.GetTaskNo().Result,
                Creater = "System",
                CreateDate = DateTime.Now,
                TaskId = 0,
                //task_bak1 = JsonConvert.SerializeObject(checkInfo)
                AGVtaskId = agvId
            };
            // åˆ›å»ºä»»åŠ¡ä¼ è¾“ç”¨çš„DTO对象
            var taskDTO = CreateTaskDTO(task);
            // èŽ·å–WMS IP地址用于发送任务请求
            var wmsIpAddress = GetWCSIpReceiveTask();
            if (wmsIpAddress == null)
            addtask schedulingTask = new addtask
            {
                throw new InvalidOperationException("WMS IP æœªé…ç½®");
            }
                task_id = task.AGVtaskId,
                task_type = task.TaskType == (int)TaskTypeEnum.Inbound ? "push" : "pop",
                work_begin = task.SourceAddress,
                work_end = task.TargetAddress
            };
            var tasks = new List<WMSTaskDTO>() { taskDTO };
            // å‘送任务请求到WMS
            var result = HttpHelper.Post(wmsIpAddress, tasks.ToJsonString());
            string address = AGV_Interface + "add_task";
            string result = HttpsClient.PostAsync(address, schedulingTask.ToDictionary()).Result;
            content = JsonConvert.DeserializeObject<WebResponseContent>(result);
            if (content.Status)
            if (content.ack != 0)
            {
                // æ·»åŠ ä»»åŠ¡åˆ°æ•°æ®åº“
                BaseDal.AddData(task);
                // æ›´æ–°åº“位位置状态为不可用
                _locationRepository.UpdateData(location);
                _palletStockInfoRepository.UpdateData(stockInfo);
                Console.WriteLine($"请求RCS异常:{content.msg}");
                LogFactory.GetLog("下发AGV任务").Info(true, $"\r\r--------------------------------------");
                LogFactory.GetLog("下发AGV任务").Info(true, $"请求参数:{schedulingTask.ToJsonString()}");
                LogFactory.GetLog("下发AGV任务").Info(true, $"响应参数:{content.ToJsonString()}");
                throw new Exception(content.msg);
            }
            _unitOfWorkManage.BeginTran();
            // æ·»åŠ ä»»åŠ¡åˆ°æ•°æ®åº“
            BaseDal.AddData(task);
            // æ›´æ–°åº“位位置状态为不可用
            _locationRepository.UpdateData(location);
            _palletStockInfoRepository.UpdateData(stockInfo);
            _unitOfWorkManage.CommitTran();
        }
        catch (Exception ex)
        {
            _unitOfWorkManage.RollbackTran();
            Console.WriteLine($"发生异常: {ex.Message}");
            content.Error(ex.Message);
        }
        return content;
    }
    private string GetWCSIpReceiveTask()
    private string GetAGVIpReceiveTask()
    {
        var configs = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress);
        var wmsBase = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.WCSIPAddress)?.ConfigValue;
        var ipAddress = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.ReceiveTask)?.ConfigValue;
        var wmsBase = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.AGVIPAddress)?.ConfigValue;
        var ipAddress = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.addTask)?.ConfigValue;
        if (wmsBase == null || ipAddress == null)
        {
            return null;
@@ -600,6 +610,20 @@
    #region private å†…部方法
    private async Task DeleteStockInfoDetailsAsync(IEnumerable<Dt_PalletStockInfoDetail> details)
    {
        if (details != null)
        {
            var ids = details.Select(x => (object)x.Id).ToArray();
            var isStockDetailUpdated = await _palletStockInfoDetailRepository.DeleteDataByIdsAsync(ids);
            if (!isStockDetailUpdated)
            {
                throw new Exception("库存详情信息更新失败");
            }
        }
    }
    /// <summary>
    /// åˆ›å»ºåŽ†å²ä»»åŠ¡è®°å½•
    /// </summary>
@@ -625,27 +649,6 @@
        return taskHty;
    }
    /// <summary>
    /// æ›´æ–°åº“存位置
    /// </summary>
    /// <param name="stock">库存对象</param>
    /// <param name="toLocation">目标位置</param>
    // æ›´æ–°åº“存和位置信息
    private (Dt_WheelsStock, DtLocationInfo, DtLocationInfo) UpdateStockLocation(Dt_WheelsStock stock, Dt_Task task)
    {
        //修改来源库位和 ç›®æ ‡åº“位状态
        var fromLocation = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway);
        fromLocation.LocationStatus = (int)LocationEnum.Free;
        var toLocation = _locationRepository.QueryFirst(x => x.LocationCode == task.TargetAddress && x.RoadwayNo == task.Roadway);
        toLocation.LocationStatus = (int)LocationEnum.InStock;
        // å°†åº“存位置设置为目标位置
        stock.Wheels_Location = task.TargetAddress;
        // è¿”回更新后的库存和位置信息
        return (stock, fromLocation, toLocation);
    }
    #region æ‰§è¡Œæ•°æ®åº“事务
    /// <summary>
    /// æ‰§è¡Œæ•°æ®åº“事务
@@ -654,30 +657,25 @@
    /// <param name="taskHty">历史任务对象</param>
    /// <param name="taskId">任务ID</param>
    /// <returns></returns>
    private async Task<bool> ExecuteTransaction(Dt_PalletStockInfo stock, Dt_Task_Hty taskHty, DtLocationInfo locationInfo, int taskId /*Dt_InWheels_mes inWheels_Mes = null*/)
    private async Task<bool> ExecuteTransaction(Dt_PalletStockInfo stock, Dt_Task_Hty taskHty, DtLocationInfo locationInfo, int taskId, DtBoxingInfo boxingInfo)
    {
        _unitOfWorkManage.BeginTran();
        try
        {
            var isUpdateStock = false;
            var isDeleteWheelsMes = false;
            var isUpdateStock = true;
            var isDeleteBoxing = true;
            // æ·»åŠ åº“å­˜
            isUpdateStock = _palletStockInfoRepository.AddData(stock) > 0;
            //if (inWheels_Mes != null)
            //{
            //    isDeleteWheelsMes = _InWheels_MesRepository.DeleteData(inWheels_Mes);
            isUpdateStock = await _palletStockInfoRepository.AddDataNavAsync(stock);
            //    //var wheels_Mes_Hty = inWheels_Mes.Adapt<Dt_InWheels_mes_hty>();
            //    //wheels_Mes_Hty.Wheels_CurrentStatue = "2";
            //    //wheels_Mes_Hty.FinishDate = DateTime.Now;
            //    //wheels_Mes_Hty.OperateType = (int)OperateTypeEnum.自动完成;
            //    //_InWheels_Mes_HtyRepository.AddData(wheels_Mes_Hty);
            //}
            //删除组盘数据
            if (boxingInfo != null)
            {
                boxingInfo.CurrentStatue = 5;
                isDeleteBoxing = await _boxingInfoRepository.Db.DeleteNav<DtBoxingInfo>(x => x.Id == boxingInfo.Id)
                                        .Include(x => x.BoxingInfoDetails)
                                        .ExecuteCommandAsync();
            }
            //var box = _boxingInfoRepository.dele(boxingInfo);
            // æ·»åŠ åŽ†å²ä»»åŠ¡
            var isTaskHtyAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0;
@@ -689,7 +687,7 @@
            var isTaskDelete = await Delete(taskId);
            // æäº¤æˆ–回滚事务
            if (isUpdateStock && isTaskHtyAdd && isTaskDelete && isUpdateLoc && isDeleteWheelsMes)
            if (isUpdateStock && isTaskHtyAdd && isTaskDelete && isUpdateLoc && isDeleteBoxing)
            {
                LogFactory.GetLog("任务完成").InfoFormat(true, "任务完成", $"事务处理完成,提交事务。添加历史任务:{isTaskHtyAdd},删除任务数据:{isTaskDelete},更新或添加库存:{isUpdateStock},修改入库前货位状态:{isUpdateLoc}");
                _unitOfWorkManage.CommitTran();
@@ -733,24 +731,24 @@
                var content = new WebResponseContent();
                // èŽ·å–åº“ä½
                var location = RequestLocation(input);
                if (location == null)
                {
                    return content.Error("无法获取货位信息");
                }
                //var location = RequestLocation(input);
                //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;
                //string toAddress = location.LocationCode;
                //int taskState = (int)TaskInStatusEnum.Line_InFinish;
                //int beforeStatus = location.LocationStatus;
                //// æ›´æ–°è´§ä½ä¿¡æ¯
                //location.LocationStatus = (int)LocationEnum.Lock;
                // æ›´æ–°ä»»åŠ¡ä¿¡æ¯
                MapTaskProperties(task, input, toAddress, taskState);
                //MapTaskProperties(task, input, toAddress, taskState);
                _unitOfWorkManage.BeginTran();
                // å¼€å§‹äº‹åŠ¡
                var isResult = await UpdateTaskAsync(task, location, beforeStatus);
                var isResult = false; //await UpdateTaskAsync(task, location, beforeStatus);
                if (!isResult)
                {
                    _unitOfWorkManage.RollbackTran();