wanshenmean
13 小时以前 343d512ed92c75f406c485fa7a247261a13aefb0
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
@@ -4,8 +4,13 @@
using WIDESEA_Core;
using WIDESEA_Core.BaseController;
using WIDESEA_DTO.Stock;
using WIDESEA_DTO.MES;
using WIDESEA_IStockService;
using WIDESEA_IBasicService;
using WIDESEA_ISystemService;
using WIDESEA_Model.Models;
using WIDESEA_Common.StockEnum;
using System.Diagnostics;
namespace WIDESEA_WMSServer.Controllers.Stock
{
@@ -16,8 +21,22 @@
    [ApiController]
    public class StockInfoController : ApiBaseController<IStockInfoService, Dt_StockInfo>
    {
        public StockInfoController(IStockInfoService service) : base(service)
        private readonly IMesLogService _mesLogService;
        private readonly IMesService _mesService;
        private readonly ISys_DictionaryService _sysDictionaryService;
        private readonly IStockInfoService _stockInfoService;
        public StockInfoController(
            IStockInfoService service,
            IMesLogService mesLogService,
            IMesService mesService,
            ISys_DictionaryService sysDictionaryService,
            IStockInfoService stockInfoService) : base(service)
        {
            _mesLogService = mesLogService;
            _mesService = mesService;
            _sysDictionaryService = sysDictionaryService;
            _stockInfoService = stockInfoService;
        }
        /// <summary>
@@ -29,7 +48,258 @@
        public async Task<WebResponseContent> Get3DLayout(int warehouseId)
        {
            var result = await Service.Get3DLayoutAsync(warehouseId);
            return WebResponseContent.Instance.OK(result);
            return WebResponseContent.Instance.OK(data: result);
        }
        /// <summary>
        /// 托盘进站 - 调用MES接口
        /// </summary>
        /// <param name="dto">进站请求参数</param>
        /// <returns>操作结果</returns>
        [HttpPost("inboundInContainer")]
        public async Task<WebResponseContent> InboundInContainer([FromBody] InboundInContainerRequestDto dto)
        {
            var response = new WebResponseContent();
            try
            {
                // 1. 参数验证
                if (string.IsNullOrWhiteSpace(dto.PalletCode))
                {
                    return response.Error("托盘编号不能为空");
                }
                // 2. 查询库存信息 - 使用单条记录查询方法提高效率
                var stockInfo = await Service.Repository.QueryDataNavFirstAsync(x => x.Id == dto.StockId);
                if (stockInfo == null)
                {
                    return response.Error("库存信息不存在");
                }
                // 3. 验证库存状态(仅"入库完成"状态允许进站)
                if (stockInfo.StockStatus != StockStatusEmun.入库完成.GetHashCode())
                {
                    return response.Error($"当前库存状态不允许进站操作,当前状态:{stockInfo.StockStatus}");
                }
                // 4. 构造MES请求
                var mesRequest = new InboundInContainerRequest
                {
                    EquipmentCode = "STK-GROUP-001",
                    ResourceCode = "STK-GROUP-001",
                    LocalTime = DateTime.Now,
                    ContainerCode = dto.PalletCode
                };
                string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest);
                string palletCode = stockInfo.PalletCode;
                // 5. 异步执行MES调用(fire-and-forget)
                _ = Task.Run(async () =>
                {
                    var localStopwatch = Stopwatch.StartNew();
                    try
                    {
                        var result = _mesService.InboundInContainer(mesRequest);
                        localStopwatch.Stop();
                        bool isSuccess = result?.IsSuccess ?? false;
                        int status = isSuccess
                            ? (int)MesUploadStatusEnum.进站上传成功
                            : (int)MesUploadStatusEnum.进站上传失败;
                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
                        await _mesLogService.LogAsync(new MesApiLogDto
                        {
                            PalletCode = palletCode,
                            ApiType = "InboundInContainer",
                            RequestJson = requestJson,
                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
                            IsSuccess = isSuccess,
                            ErrorMessage = result?.ErrorMessage ?? "未知错误",
                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
                            Creator = App.User.UserName
                        });
                    }
                    catch (Exception ex)
                    {
                        localStopwatch.Stop();
                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.进站上传失败);
                        await _mesLogService.LogAsync(new MesApiLogDto
                        {
                            PalletCode = palletCode,
                            ApiType = "InboundInContainer",
                            IsSuccess = false,
                            ErrorMessage = ex.Message,
                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
                            Creator = App.User.UserName
                        });
                    }
                });
                // 6. 立即返回成功
                return response.OK("托盘进站成功");
            }
            catch (System.Exception ex)
            {
                return response.Error($"托盘进站失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 托盘出站 - 调用MES接口
        /// </summary>
        /// <param name="dto">出站请求参数</param>
        /// <returns>操作结果</returns>
        [HttpPost("outboundInContainer")]
        public async Task<WebResponseContent> OutboundInContainer([FromBody] OutboundInContainerRequestDto dto)
        {
            var response = new WebResponseContent();
            try
            {
                // 1. 参数验证
                if (string.IsNullOrWhiteSpace(dto.PalletCode))
                {
                    return response.Error("托盘编号不能为空");
                }
                // 2. 查询库存信息 - 使用单条记录查询方法提高效率
                var stockInfo = await Service.Repository.QueryDataNavFirstAsync(x => x.Id == dto.StockId);
                if (stockInfo == null)
                {
                    return response.Error("库存信息不存在");
                }
                // 3. 验证库存状态("出库锁定"或"出库完成"状态允许出站)
                var allowedStatuses = new[]
                {
                    StockStatusEmun.出库锁定.GetHashCode(),
                    StockStatusEmun.出库完成.GetHashCode()
                };
                if (!allowedStatuses.Contains(stockInfo.StockStatus))
                {
                    return response.Error($"当前库存状态不允许出站操作,当前状态:{stockInfo.StockStatus}");
                }
                // 4. 构造MES请求
                var mesRequest = new OutboundInContainerRequest
                {
                    EquipmentCode = "STK-GROUP-001",
                    ResourceCode = "STK-GROUP-001",
                    LocalTime = DateTime.Now,
                    ContainerCode = dto.PalletCode,
                    ParamList = dto.ParamList?.Select(p => new ParamItem
                    {
                        ParamCode = p.ParamCode,
                        ParamValue = p.ParamValue,
                        CollectionTime = DateTime.TryParse(p.CollectionTime, out var ct) ? ct : DateTime.Now
                    }).ToList()
                };
                string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest);
                string palletCode = stockInfo.PalletCode;
                // 5. 异步执行MES调用(fire-and-forget)
                _ = Task.Run(async () =>
                {
                    var localStopwatch = Stopwatch.StartNew();
                    try
                    {
                        var result = _mesService.OutboundInContainer(mesRequest);
                        localStopwatch.Stop();
                        bool isSuccess = result?.IsSuccess ?? false;
                        int status = isSuccess
                            ? (int)MesUploadStatusEnum.出站上传成功
                            : (int)MesUploadStatusEnum.出站上传失败;
                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
                        await _mesLogService.LogAsync(new MesApiLogDto
                        {
                            PalletCode = palletCode,
                            ApiType = "OutboundInContainer",
                            RequestJson = requestJson,
                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
                            IsSuccess = isSuccess,
                            ErrorMessage = result?.ErrorMessage ?? "未知错误",
                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
                            Creator = App.User.UserName
                        });
                    }
                    catch (Exception ex)
                    {
                        localStopwatch.Stop();
                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.出站上传失败);
                        await _mesLogService.LogAsync(new MesApiLogDto
                        {
                            PalletCode = palletCode,
                            ApiType = "OutboundInContainer",
                            IsSuccess = false,
                            ErrorMessage = ex.Message,
                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
                            Creator = App.User.UserName
                        });
                    }
                });
                // 6. 立即返回成功
                return response.OK("托盘出站成功");
            }
            catch (System.Exception ex)
            {
                return response.Error($"托盘出站失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 从配置字典中获取配置值
        /// </summary>
        /// <param name="configs">配置字典列表</param>
        /// <param name="key">配置键</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>配置值</returns>
        private string GetConfigValue(System.Collections.Generic.List<WIDESEA_DTO.System.VueDictionaryDTO> configs, string key, string defaultValue = "")
        {
            if (configs != null)
            {
                var config = configs.FirstOrDefault(c => c.DicNo == key);
                if (config != null && config.Data != null)
                {
                    // Data是dynamic类型,尝试获取第一个元素的value属性
                    try
                    {
                        // 使用dynamic来访问匿名类型的属性
                        dynamic data = config.Data;
                        if (data != null)
                        {
                            // data可能是IEnumerable或者单个对象
                            var enumerable = data as System.Collections.IEnumerable;
                            if (enumerable != null)
                            {
                                foreach (var item in enumerable)
                                {
                                    // 获取第一个元素
                                    dynamic firstItem = item;
                                    var value = firstItem.value;
                                    return value?.ToString() ?? defaultValue;
                                }
                            }
                        }
                    }
                    catch
                    {
                        // 如果无法获取,返回默认值
                        return defaultValue;
                    }
                }
            }
            return defaultValue;
        }
    }
}