wanshenmean
2026-02-26 3de39066b5894850d0f0dc311b60cc09f599a025
Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs
@@ -1,6 +1,7 @@
using SqlSugar;
using WIDESEA_Common.CommonEnum;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
@@ -14,9 +15,14 @@
    public partial class LocationInfoService : ServiceBase<Dt_LocationInfo, IRepository<Dt_LocationInfo>>, ILocationInfoService
    {
        public IRepository<Dt_LocationInfo> Repository => BaseDal;
        public IRepository<Dt_Task> _taskRepository { get; }
        public LocationInfoService(IRepository<Dt_LocationInfo> BaseDal) : base(BaseDal)
        public IRepository<Dt_StockInfo> _stockInfoRepository { get; set; }
        public LocationInfoService(IRepository<Dt_LocationInfo> BaseDal, IRepository<Dt_Task> taskRepository, IRepository<Dt_StockInfo> stockInfoRepository) : base(BaseDal)
        {
            _taskRepository = taskRepository;
            _stockInfoRepository = stockInfoRepository;
        }
        /// <summary>
@@ -142,6 +148,11 @@
            return await BaseDal.QueryFirstAsync(x => x.RoadwayNo == roadwayNo && x.LocationCode == locationCode);
        }
        public async Task<Dt_LocationInfo> GetLocationInfoAsync( string locationCode)
        {
            return await BaseDal.QueryFirstAsync(x=>x.LocationCode == locationCode);
        }
        /// <summary>
        /// 更新货位信息
        /// </summary>
@@ -149,5 +160,141 @@
        {
            return await BaseDal.UpdateDataAsync(locationInfo);
        }
        /// <summary>
        /// 检查并生成移库任务或返回出库任务
        /// </summary>
        /// <param name="locationID">任务号</param>
        /// <returns>任务对象</returns>
        public async Task<Dt_Task> TransferCheckAsync(int taskNum)
        {
            try
            {
                // 根据任务号获取任务
                var outboundTask = await _taskRepository.QueryFirstAsync(x => x.TaskNum == taskNum);
                if (outboundTask == null)
                    return null;
                var location = await BaseDal.QueryFirstAsync(x => x.LocationCode == outboundTask.SourceAddress);
                // 检查是否需要进行移库
                if (CheckForInternalTransfer(location))
                {
                    // 计算对应位置的相对库位 (奇数行的下一行或者偶数行的上一行)
                    var newLocationID = GetRelativeLocationID(location);
                    // 获取新的库位的任务
                    var internalTransferTask = await _taskRepository.QueryFirstAsync(x => x.SourceAddress == newLocationID && x.Roadway == outboundTask.Roadway);
                    // 如果新的库位没有找到对应的任务
                    if (internalTransferTask == null)
                    {
                        return await HandleNoTaskAtLocation(outboundTask.SourceAddress, newLocationID, outboundTask);
                    }
                    // 直接返回一深位出库任务
                    return internalTransferTask;
                }
                // 返回当前库位的出库任务
                return outboundTask;
            }
            catch (Exception)
            {
                return null;
            }
        }
        #region 移库方法
        /// <summary>
        /// 计算相对的库位ID
        /// </summary>
        /// <param name="locationID">当前库位ID</param>
        /// <returns>相对的库位ID</returns>
        private string GetRelativeLocationID(Dt_LocationInfo locationInfo)
        {
            int line = locationInfo.Row;
            // 计算相对的货位行值,奇数行的下一行或者偶数行的上一行
            int relativeLine = line % 2 == 1 ? line + 1 : line - 1;
            // 构建新的库位ID
            string[] newLocationParts = new string[] { relativeLine.ToString().PadLeft(3, '0'), locationInfo.Column.ToString(), locationInfo.Layer.ToString() };
            return string.Join("-", newLocationParts);
        }
        /// <summary>
        /// 处理没有任务的库位情况
        /// </summary>
        /// <param name="originalLocationID">原始库位ID</param>
        /// <param name="newLocationID">新的库位ID</param>
        /// <param name="outboundTask">出库任务</param>
        /// <returns>生成的移库任务或原始出库任务</returns>
        private async Task<Dt_Task> HandleNoTaskAtLocation(string originalLocationID, string newLocationID, Dt_Task outboundTask)
        {
            // 判断该位置是否有库存
            var stockInfo = await _stockInfoRepository.QueryFirstAsync(x => x.LocationCode == newLocationID);
            if (stockInfo == null)
            {
                // 如果没有库存,直接返回当前出库任务
                return outboundTask;
            }
            else
            {
                // 如果有库存,生成移库任务
                var emptyLocation = await GetTransferLocationEmptyAsync(outboundTask.Roadway);
                var taskNo = await _taskRepository.GetTaskNo();
                Dt_Task newTransferTask = new Dt_Task()
                {
                    CreateDate = DateTime.Now,
                    Creater = App.User.UserName,
                    CurrentAddress = originalLocationID,
                    Grade = 99,
                    NextAddress = emptyLocation.LocationCode,
                    PalletCode = stockInfo.PalletCode,
                    Remark = "移库",
                    Roadway = stockInfo.LocationDetails.RoadwayNo,
                    SourceAddress = originalLocationID,
                    TaskNum = taskNo,
                    TargetAddress = emptyLocation.LocationCode,
                    TaskType = TaskTypeEnum.Relocation.GetHashCode(),
                };
                return await _taskRepository.Db.Insertable(newTransferTask).ExecuteReturnEntityAsync();
            }
        }
        /// <summary>
        /// 根据货位是否需要移库
        /// </summary>
        /// <param name="locationID">货位ID</param>
        /// <returns>是否需要移库</returns>
        private bool CheckForInternalTransfer(Dt_LocationInfo location)
        {
            return location.Depth == 2 ? true : false;
        }
        /// <summary>
        /// 根据巷道获取二深位的空库位
        /// </summary>
        /// <param name="roadway">巷道</param>
        /// <returns>货位对象</returns>
        private async Task<Dt_LocationInfo> GetTransferLocationEmptyAsync(string roadway)
        {
            return await BaseDal.QueryFirstAsync(x => x.Depth == 2 && x.LocationStatus == (LocationStatusEnum.Free.GetHashCode()) && x.RoadwayNo == roadway);
            //Db.Queryable<Dt_LocationInfo>()
            //.Where(x => x.Status == LocationEnum.Free.ObjToInt())
            //.Where(x => x.Depth == 2.ToString())
            //.Where(x => x.Roadway == roadway)
            //.First();
        }
        #endregion 移库方法
    }
}