using FileService.Application.UploadFile; using FileService.Infrastructure; using IM.ASPNETCore; using IM.Commons; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace FileService.WebApi.Controllers.File { [Authorize] [Route("api/[controller]")] [ApiController] public class FileController : ControllerBase { private readonly UploadFileService service; public FileController(UploadFileService service) { this.service = service; } /// /// 单次直传(小文件:头像/封面等)。isPublic=true 落公开桶,返回直链。 /// 支持秒传:若相同 checksum 的文件已存在,直接返回已有记录,跳过上传。 /// [HttpPost("simple-upload")] [UnitOfWork(typeof(FileDbContext))] public async Task SimpleUpload([FromForm] IFormFile file, [FromForm] bool isPublic) { if (file == null || file.Length == 0) { return BadRequest(); } var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); await using var stream = file.OpenReadStream(); var res = await service.SimpleUploadAsync(new SimpleUploadCommand( OwnerId: Guid.Parse(userId), FileName: file.FileName, ContentType: file.ContentType, FileSize: file.Length, Content: stream, IsPublic: isPublic)); return Ok(res); } /// /// 获取文件信息(含直链 Url;私有文件 Url 为 null)。 /// [HttpGet("{id}")] public async Task Get(Guid id) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var res = await service.GetFileInfoAsync(id, Guid.Parse(userId)); return Ok(res); } /// /// 鉴权下载文件内容(私有文件预览/下载走这里)。 /// [HttpGet("{id}/content")] public async Task GetContent(Guid id) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var res = await service.OpenDownloadAsync(id, Guid.Parse(userId)); if (res.Data == null) { if (res.Code == (int)ResultCode.PERMISSION_DENIED) { return StatusCode(StatusCodes.Status403Forbidden, res); } return NotFound(res); } Response.Headers["Cache-Control"] = "private,max-age=86400"; return File(res.Data.Content, res.Data.ContentType, enableRangeProcessing: true); } } }