using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Mvc;
|
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
|
{
|
/// <summary>
|
/// 库存
|
/// </summary>
|
[Route("api/StockInfo")]
|
[ApiController]
|
public class StockInfoController : ApiBaseController<IStockInfoService, Dt_StockInfo>
|
{
|
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>
|
/// 获取仓库3D布局
|
/// </summary>
|
/// <param name="warehouseId">仓库ID</param>
|
/// <returns>3D布局数据</returns>
|
[HttpGet("Get3DLayout")]
|
public async Task<WebResponseContent> Get3DLayout(int warehouseId)
|
{
|
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;
|
}
|
}
|
}
|