using System.Net.NetworkInformation;
using System.Net.Sockets;
using AgriculturalPlatform.Api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AgriculturalPlatform.Api.Controllers;
///
/// 附件上传(身份证正反面):高拍仪/本地拍照直传 + 手机扫码上传。
/// 图片保存为附件(本地存储,OSS 配置后自动切换),并返回 OCR 识别结果。
///
[ApiController]
[Route("api/uploads")]
public class UploadsController(
IFileStorage storage,
IOcrService ocr,
MobileUploadSessionStore sessions,
IConfiguration cfg) : ControllerBase
{
///
/// 高拍仪/本地拍照:上传身份证单面图片(side = front 正面 | back 反面),
/// 返回附件地址(url/key)与 OCR 识别结果。
///
[HttpPost("idcard")]
[Authorize]
[RequestSizeLimit(15 * 1024 * 1024)]
public async Task UploadIdCard(IFormFile? file, [FromForm] string? side)
{
if (file is null || file.Length == 0)
return BadRequest(new { message = "请先拍摄或选择身份证图片" });
side = side == "back" ? "back" : "front";
await using var ms = new MemoryStream();
await file.CopyToAsync(ms);
ms.Position = 0;
StoredFile saved;
try
{
saved = await storage.SaveAsync("idcard", ms, file.FileName, file.ContentType);
}
catch (InvalidOperationException ex)
{
return BadRequest(new { message = ex.Message });
}
// 反面仅存档至 OSS,不调用 OCR(OCR 只识别正面)
IdCardOcrResult? result = null;
if (side == "front")
result = await ocr.RecognizeAsync(ms, side, file.FileName, saved.Key);
return Ok(new { url = saved.Url, key = saved.Key, side, ocr = result });
}
///
/// 手机传图:创建上传会话,返回二维码内容(手机访问的 URL)。
/// 电脑端展示二维码,手机扫码后访问 /mobile-upload.html?code=xxx 上传身份证正反面。
/// 注意:端口固定取 Server:LanPort(默认 5246),不依赖请求 Host,
/// 因为经 Vite 代理(5173)访问时 Host 端口可能是前端端口,手机无法访问该端口。
///
[HttpGet("qr")]
[Authorize]
public ActionResult