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 };
}
}