fix: bat uses dotnet directly, doctor frontend gets port 5174

This commit is contained in:
MingNian
2026-05-21 15:20:55 +08:00
parent 51c7c89ec5
commit 3ef25e734f
9 changed files with 358 additions and 83 deletions

View File

@@ -0,0 +1,104 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace HealthManager.WebApi.Controllers;
[ApiController]
[Route("api/files")]
[Authorize]
public class FileController : ControllerBase
{
private static readonly string UploadDir = Path.Combine(
Directory.GetCurrentDirectory(), "..", "..", "..", "data", "uploads");
public FileController()
{
if (!Directory.Exists(UploadDir))
Directory.CreateDirectory(UploadDir);
}
[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest(new { message = "No file selected" });
if (file.Length > 10 * 1024 * 1024)
return BadRequest(new { message = "File too large (max 10MB)" });
var allowedTypes = new[] { "image/jpeg", "image/png", "image/gif", "image/webp", "application/pdf" };
if (!allowedTypes.Contains(file.ContentType.ToLower()))
return BadRequest(new { message = "Unsupported file type" });
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var filePath = Path.Combine(UploadDir, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var url = $"/api/files/{fileName}";
return Ok(new { url, fileName });
}
[HttpPost("upload-multiple")]
public async Task<IActionResult> UploadMultiple(List<IFormFile> files)
{
if (files == null || files.Count == 0)
return BadRequest(new { message = "No files selected" });
var results = new List<object>();
foreach (var file in files)
{
if (file.Length == 0) continue;
if (file.Length > 10 * 1024 * 1024) continue;
var allowedTypes = new[] { "image/jpeg", "image/png", "image/gif", "image/webp", "application/pdf" };
if (!allowedTypes.Contains(file.ContentType.ToLower())) continue;
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var filePath = Path.Combine(UploadDir, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
results.Add(new { url = $"/api/files/{fileName}", fileName });
}
return Ok(results);
}
[HttpGet("{fileName}")]
[AllowAnonymous]
public IActionResult Download(string fileName)
{
var filePath = Path.Combine(UploadDir, fileName);
// Security: prevent path traversal
if (!filePath.StartsWith(UploadDir))
return NotFound();
if (!System.IO.File.Exists(filePath))
return NotFound();
var contentType = GetContentType(fileName);
return PhysicalFile(filePath, contentType);
}
private static string GetContentType(string fileName)
{
var ext = Path.GetExtension(fileName).ToLower();
return ext switch
{
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".webp" => "image/webp",
".pdf" => "application/pdf",
_ => "application/octet-stream",
};
}
}