Files
Migu2.0/MiGu.Server/Controllers/WmsController.cs
T
ArtoriasWu f2ef32a22b 引入WMS仓储主数据与关系管理全流程能力
后端实现基于EF Core的库区/库位/容器/物料/关系/历史等模型、服务与RESTful接口,支持多数据库Provider。前端新增类型、API与聚合页面,支持主数据及容器位置/物料关系的增删改查、绑定/解绑、装料/卸料、历史追溯。完善权限、菜单与文档,平台具备完整WMS能力。
2026-06-22 09:15:42 +08:00

144 lines
5.9 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using MiGu.Server.Wms;
namespace MiGu.Server.Controllers;
[ApiController]
[Authorize]
[TypeFilter(typeof(WmsExceptionFilter))]
[Route("api/wms")]
public sealed class WmsController : ControllerBase
{
private readonly WmsService _service;
public WmsController(WmsService service)
{
_service = service;
}
[HttpGet("areas")]
public Task<List<WarehouseArea>> Areas([FromQuery] string? q) => _service.Areas(q);
[HttpPost("areas")]
public async Task<IActionResult> SaveArea([FromBody] MasterDataRequest req) => Ok(await _service.SaveArea(req, User.ActorName()));
[HttpPut("areas/{id:guid}")]
public async Task<IActionResult> UpdateArea(Guid id, [FromBody] MasterDataRequest req) =>
Ok(await _service.SaveArea(req with { Id = id }, User.ActorName()));
[HttpDelete("areas/{id:guid}")]
public async Task<IActionResult> DeleteArea(Guid id, [FromQuery] long? version)
{
await _service.DeleteEntity<WarehouseArea>(id, version, User.ActorName());
return NoContent();
}
[HttpGet("storages")]
public Task<List<Storage>> Storages([FromQuery] string? q) => _service.Storages(q);
[HttpPost("storages")]
public async Task<IActionResult> SaveStorage([FromBody] StorageRequest req) => Ok(await _service.SaveStorage(req, User.ActorName()));
[HttpPut("storages/{id:guid}")]
public async Task<IActionResult> UpdateStorage(Guid id, [FromBody] StorageRequest req) =>
Ok(await _service.SaveStorage(req with { Id = id }, User.ActorName()));
[HttpDelete("storages/{id:guid}")]
public async Task<IActionResult> DeleteStorage(Guid id, [FromQuery] long? version)
{
await _service.DeleteEntity<Storage>(id, version, User.ActorName());
return NoContent();
}
[HttpGet("containers")]
public Task<List<Container>> Containers([FromQuery] string? q) => _service.Containers(q);
[HttpPost("containers")]
public async Task<IActionResult> SaveContainer([FromBody] MasterDataRequest req) => Ok(await _service.SaveContainer(req, User.ActorName()));
[HttpPut("containers/{id:guid}")]
public async Task<IActionResult> UpdateContainer(Guid id, [FromBody] MasterDataRequest req) =>
Ok(await _service.SaveContainer(req with { Id = id }, User.ActorName()));
[HttpDelete("containers/{id:guid}")]
public async Task<IActionResult> DeleteContainer(Guid id, [FromQuery] long? version)
{
await _service.DeleteEntity<Container>(id, version, User.ActorName());
return NoContent();
}
[HttpGet("materials")]
public Task<List<Material>> Materials([FromQuery] string? q) => _service.Materials(q);
[HttpPost("materials")]
public async Task<IActionResult> SaveMaterial([FromBody] MaterialRequest req) => Ok(await _service.SaveMaterial(req, User.ActorName()));
[HttpPut("materials/{id:guid}")]
public async Task<IActionResult> UpdateMaterial(Guid id, [FromBody] MaterialRequest req) =>
Ok(await _service.SaveMaterial(req with { Id = id }, User.ActorName()));
[HttpDelete("materials/{id:guid}")]
public async Task<IActionResult> DeleteMaterial(Guid id, [FromQuery] long? version)
{
await _service.DeleteEntity<Material>(id, version, User.ActorName());
return NoContent();
}
[HttpGet("container-locations")]
public Task<List<ContainerLocation>> ContainerLocations([FromQuery] string? locationType, [FromQuery] string? q) =>
_service.ContainerLocations(locationType, q);
[HttpPost("container-locations")]
public async Task<IActionResult> SaveContainerLocation([FromBody] ContainerLocationRequest req) =>
Ok(await _service.BindOrTransferLocation(req, User.ActorName()));
[HttpPost("container-locations/transfer")]
public async Task<IActionResult> TransferContainerLocation([FromBody] ContainerLocationRequest req) =>
Ok(await _service.BindOrTransferLocation(req, User.ActorName()));
[HttpDelete("container-locations/{containerId:guid}")]
public async Task<IActionResult> UnbindContainerLocation(Guid containerId, [FromQuery] string? reason)
{
await _service.UnbindLocation(containerId, User.ActorName(), reason ?? "");
return NoContent();
}
[HttpGet("container-materials")]
public Task<List<ContainerMaterial>> ContainerMaterials([FromQuery] string? q) => _service.ContainerMaterials(q);
[HttpPost("container-materials")]
public async Task<IActionResult> SaveContainerMaterial([FromBody] ContainerMaterialRequest req) =>
Ok(await _service.SaveContainerMaterial(req, User.ActorName()));
[HttpPut("container-materials/{id:guid}")]
public async Task<IActionResult> UpdateContainerMaterial(Guid id, [FromBody] ContainerMaterialRequest req) =>
Ok(await _service.SaveContainerMaterial(req with { Id = id }, User.ActorName()));
[HttpDelete("container-materials/{id:guid}")]
public async Task<IActionResult> UnloadContainerMaterial(Guid id, [FromQuery] string? reason)
{
await _service.UnloadMaterial(id, User.ActorName(), reason ?? "");
return NoContent();
}
[HttpGet("container-location-history")]
public Task<List<ContainerLocationHistory>> ContainerLocationHistory([FromQuery] Guid? containerId) =>
_service.LocationHistory(containerId);
[HttpGet("container-material-history")]
public Task<List<ContainerMaterialHistory>> ContainerMaterialHistory([FromQuery] Guid? containerId, [FromQuery] Guid? materialId) =>
_service.MaterialHistory(containerId, materialId);
}
public sealed class WmsExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (context.Exception is not InvalidOperationException ex) return;
context.Result = new BadRequestObjectResult(new { message = ex.Message });
context.ExceptionHandled = true;
}
}