| | |
| | | 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 |
| | | { |
| | |
| | | [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; |
| | | |
| | | public StockInfoController( |
| | | IStockInfoService service, |
| | | IMesLogService mesLogService, |
| | | IMesService mesService, |
| | | ISys_DictionaryService sysDictionaryService) : base(service) |
| | | { |
| | | _mesLogService = mesLogService; |
| | | _mesService = mesService; |
| | | _sysDictionaryService = sysDictionaryService; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | var result = await Service.Get3DLayoutAsync(warehouseId); |
| | | 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(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | 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); |
| | | |
| | | // 5. 调用MES接口(同步方法) |
| | | var mesResult = _mesService.InboundInContainer(mesRequest); |
| | | stopwatch.Stop(); |
| | | |
| | | // 6. 记录日志 |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "InboundInContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 7. 返回结果 |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("托盘进站成功"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MES接口调用失败: {mesResult.ErrorMessage}"); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // 记录错误日志 |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "InboundInContainer", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | 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(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | 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); |
| | | |
| | | // 5. 调用MES接口(同步方法) |
| | | var mesResult = _mesService.OutboundInContainer(mesRequest); |
| | | stopwatch.Stop(); |
| | | |
| | | // 6. 记录日志 |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "OutboundInContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 7. 返回结果 |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("托盘出站成功"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MES接口调用失败: {mesResult.ErrorMessage}"); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // 记录错误日志 |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "OutboundInContainer", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | 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; |
| | | } |
| | | } |
| | | } |