新增分段管理

This commit is contained in:
18086616529
2026-06-23 17:22:40 +08:00
parent a6086f1f8b
commit 88c688c0df
19 changed files with 1882 additions and 1 deletions
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace MiGu.Server.Controllers;
/// <summary>
/// 投影 API 占位:真实落地时由 YARP 反代到 SimpleLite WebAPI 的 /api/projection/* 路径。
/// 本地 Mock 数据仅用于无 SimpleLite 运行时的开发联调。
///
/// AR-4: 全 class 加 [Authorize] —— 任何登录用户都能读 mock 投影数据;未登录直接 401。
/// </summary>
[ApiController]
[Authorize]
[Route("api/projection")]
public class ProjectionController : ControllerBase
{
[HttpGet("sites")]
public IActionResult Sites() => Ok(new[]
{
new { id = "S001", name = "A 区-入库点", x = 1000, y = 2000 },
new { id = "S002", name = "A 区-出库点", x = 3000, y = 2000 },
new { id = "S003", name = "B 区-缓存区", x = 5000, y = 2000 }
});
[HttpGet("tracks")]
public IActionResult Tracks() => Ok(new[]
{
new { id = "T001", kind = "line", fromSiteId = "S001", toSiteId = "S002" },
new { id = "T002", kind = "line", fromSiteId = "S002", toSiteId = "S003" }
});
[HttpGet("cars")]
public IActionResult Cars() => Ok(new[]
{
new { id = "C01", name = "AGV-001", state = "running", batterySoc = 0.86 },
new { id = "C02", name = "AGV-002", state = "idle", batterySoc = 0.42 }
});
[HttpGet("missions")]
public IActionResult Missions() => Ok(new[]
{
new { id = "M01", name = "A 区送料 #1", status = "running", priority = 50 },
new { id = "M02", name = "A→B 缓存搬运", status = "queued", priority = 60 }
});
}
@@ -0,0 +1,85 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using MiGu.Server.SimpleFields;
namespace MiGu.Server.Controllers;
/// <summary>
/// Simple 字段管理 API:按车型维护 site / track / plan / car 四类反射字段的默认值与多语言名称。
/// 数据持久化于 <c>platform.db</c> 的 <c>simple_fields</c> 表。
///
/// 对应前端「字段管理」页(<c>/admin/simple-fields</c>,页面 key <c>admin-simple-fields</c>)。
/// 前端主流程为「刷新」读库、「默认」从 SimpleLite 拉取模板、「保存」走 <see cref="SaveBatch"/> 全量替换。
/// </summary>
[ApiController]
[Authorize]
[TypeFilter(typeof(SimpleFieldExceptionFilter))]
[Route("api/simple-fields")]
public sealed class SimpleFieldController : ControllerBase
{
private readonly SimpleFieldService _service;
public SimpleFieldController(SimpleFieldService service) => _service = service;
/// <summary>
/// 查询字段列表,支持按字段类型、车型与关键字过滤。
/// 结果按 car_type → field_type → key 排序。
/// </summary>
/// <param name="fieldType">字段类型,如 <c>siteFields</c>、<c>carFields</c>。</param>
/// <param name="carType">车型唯一标识:<c>assemblyName.shortName</c>。</param>
/// <param name="q">关键字,匹配 key / car_type / 中英文名 / 其他语言 / 默认值。</param>
[HttpGet]
public Task<List<SimpleField>> List([FromQuery] string? fieldType, [FromQuery] string? carType, [FromQuery] string? q) => _service.ListAsync(fieldType, carType, q);
/// <summary>
/// 新增单条字段;同车型 + 字段类型下 key 不可重复
/// </summary>
[HttpPost]
public Task<SimpleField> Create([FromBody] SimpleFieldRequest req) => _service.SaveAsync(req);
/// <summary>
/// 按 id 更新单条字段
/// </summary>
[HttpPut("{id:guid}")]
public Task<SimpleField> Update(Guid id, [FromBody] SimpleFieldRequest req) => _service.SaveAsync(req with { Id = id });
/// <summary>
/// 按 id 删除单条字段
/// </summary>
[HttpDelete("{id:guid}")]
public async Task<IActionResult> Delete(Guid id)
{
await _service.DeleteAsync(id);
return NoContent();
}
/// <summary>
/// 批量保存字段
/// <paramref name="req"/>.<see cref="SimpleFieldBatchRequest.ReplaceAll"/> 为 <c>true</c> 时先清空表再写入(前端「保存」使用此模式)。
/// 返回实际写入条数 <c>{ count }</c>。
/// </summary>
[HttpPost("batch")]
public async Task<IActionResult> SaveBatch([FromBody] SimpleFieldBatchRequest req)
{
var count = await _service.SaveBatchAsync(req);
return Ok(new { count });
}
}
/// <summary>
/// 将 <see cref="SimpleFieldException"/> 转为 HTTP 400,响应体 <c>{ message }</c>
/// </summary>
public sealed class SimpleFieldExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (context.Exception is not SimpleFieldException ex) { return; }
context.Result = new BadRequestObjectResult(new { message = ex.Message });
context.ExceptionHandled = true;
}
}