using F9MES.Application.Print; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace F9MES.Api.Controllers; /// /// 打印对接接口(OpenPrint 后端契约,见 openprint/src/repository/*) /// 注意:与 F9 其它接口不同,此处返回【裸 JSON】而非 ApiResult 信封: /// - 列表:{ items, total } /// - 详情/创建/更新:资源对象 /// - 删除:204 无 body /// - 错误:{ code, message, detail, requestId } /// 鉴权复用 F9 的 JWT(openprint 侧自动注入 Authorization: Bearer {token})。 /// [ApiController] [Authorize] [Route("api/print")] public class PrintApiController : ControllerBase { private readonly PrintService _print; public PrintApiController(PrintService print) { _print = print; } // ==================== 模板 ==================== /// 模板列表(不含 content) [HttpGet("templates")] public async Task GetTemplates() { var (items, total) = await _print.ListTemplatesAsync(); return Ok(new { items, total }); } /// 模板详情(含 content,TemplateJSON 字符串) [HttpGet("templates/{id}")] public async Task GetTemplate(string id) { var row = await _print.GetTemplateAsync(id); if (row == null) return Err(StatusCodes.Status404NotFound, "模板不存在", $"id={id}"); return Ok(row); } /// 创建模板(201 + 含真实 id 的资源) [HttpPost("templates")] public async Task CreateTemplate([FromBody] PrintTemplateInput input) { if (input == null || string.IsNullOrWhiteSpace(input.Name)) return Err(StatusCodes.Status400BadRequest, "模板名称不能为空"); var row = await _print.CreateTemplateAsync(input); return StatusCode(StatusCodes.Status201Created, row); } /// 更新模板(部分字段;openprint 发 name 和/或 content) [HttpPut("templates/{id}")] public async Task UpdateTemplate(string id, [FromBody] PrintTemplateInput input) { if (input == null) return Err(StatusCodes.Status400BadRequest, "请求体不能为空"); var row = await _print.UpdateTemplateAsync(id, input); if (row == null) return Err(StatusCodes.Status404NotFound, "模板不存在", $"id={id}"); return Ok(row); } /// 物理删除模板(204 无 body) [HttpDelete("templates/{id}")] public async Task DeleteTemplate(string id) { var ok = await _print.DeleteTemplateAsync(id); if (!ok) return Err(StatusCodes.Status404NotFound, "模板不存在", $"id={id}"); return NoContent(); } // ==================== 数据源 ==================== /// 数据源列表(含子表层级 tables) [HttpGet("data-sources")] public IActionResult GetDataSources() { var items = _print.ListDataSources(); return Ok(new { items, total = items.Count }); } /// 数据源字段定义 [HttpGet("data-sources/{id}/fields")] public IActionResult GetFields(string id) { var items = _print.ListFields(id); return Ok(new { items, total = items.Count }); } /// 统一错误信封:{ code, message, detail, requestId } private IActionResult Err(int status, string message, string? detail = null) { return new JsonResult(new { code = status, message, detail, requestId = HttpContext.TraceIdentifier, }) { StatusCode = status }; } }