using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Text; using WIDESEA_Core; using WIDESEA_Core.BaseController; using WIDESEA_ISystemService; using WIDESEA_Model.Models; namespace WIDESEA_WMSServer.Controllers { /// /// 日志 /// [Route("api/Sys_Log")] [ApiController] public class Sys_LogController : ApiBaseController { public Sys_LogController(ISys_LogService service) : base(service) { } [HttpPost, Route("GetLogName"), AllowAnonymous] public WebResponseContent GetLogName() { WebResponseContent content = new WebResponseContent(); try { List data = new List(); DirectoryInfo folder = new DirectoryInfo(AppContext.BaseDirectory + "\\logs\\"); DirectoryInfo[] firstDirectoryInfos = folder.GetDirectories().OrderByDescending(x => x.CreationTime).ToArray(); int k = 2020; for (int i = 0; i < firstDirectoryInfos.Length; i++) { if (firstDirectoryInfos[i].Name != "Info") { FileInfo[] nextFileInfos = firstDirectoryInfos[i].GetFiles(); List values = new List(); for (int j = 0; j < nextFileInfos.Length; j++) { values.Add(new { label = nextFileInfos[j].Name, id = k, hidden = true, fatherNode = firstDirectoryInfos[i].Name }); k++; } data.Add(new { label = firstDirectoryInfos[i].Name, children = values, id = i, hidden = false }); } } FileInfo[] nextFileInfo = folder.GetFiles(); List value = new List(); for (int j = 0; j < nextFileInfo.Length; j++) { value.Add(new { label = nextFileInfo[j].Name, id = k, hidden = true, fatherNode = folder.Name }); k++; } data.Add(new { label = folder.Name, children = value, id = 1, hidden = false }); return WebResponseContent.Instance.OK(data: data); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } [HttpPost, Route("GetLog"), AllowAnonymous] public WebResponseContent GetLog(string fileName) { WebResponseContent content = new WebResponseContent(); try { List files = new List(); DirectoryInfo folder = new DirectoryInfo(AppContext.BaseDirectory + "\\logs\\"); DirectoryInfo[] firstDirectoryInfos = folder.GetDirectories(); for (int i = 0; i < firstDirectoryInfos.Length; i++) { FileInfo[] nextFileInfos = firstDirectoryInfos[i].GetFiles(); files.AddRange(nextFileInfos); } FileInfo[] nextFileInfo = folder.GetFiles(); files.AddRange(nextFileInfo); if (files.Count > 0) { FileInfo file = files.Where(x => x.Name == fileName).FirstOrDefault(); using StreamReader stream = new StreamReader(file.FullName); StringBuilder text = new StringBuilder(); List lines = new List(); int i = 0; while (stream.Peek() >= 0) { var line = stream.ReadLine(); lines.Add(line); } content = WebResponseContent.Instance.OK(data: lines); } else { content = WebResponseContent.Instance.Error($"未找到日志文件,【{fileName}】"); } } catch (Exception ex) { content = WebResponseContent.Instance.Error($"打开日志文件错误,{ex.Message}"); } return content; } [HttpPost, HttpGet, Route("DownLoadLog"), AllowAnonymous] public virtual ActionResult DownLoadLog(string fileName) { try { // 1. 参数验证 if (string.IsNullOrWhiteSpace(fileName)) { return BadRequest("文件名不能为空"); } //string logDirectory = Path.Combine(AppContext.BaseDirectory, "logs"); string logDirectory = Path.Combine(AppContext.BaseDirectory); if (!Directory.Exists(logDirectory)) { Directory.CreateDirectory(logDirectory); } string filePath = Path.Combine(logDirectory, fileName); if (Directory.Exists(filePath)) { return NotFound($"文件 {fileName} 不存在"); } string extension = Path.GetExtension(fileName).ToLowerInvariant(); if (!IsAllowedFileType(extension)) { return BadRequest($"不支持的文件类型: {extension}"); } FileInfo fileInfo = new FileInfo(filePath); if (fileInfo.Length > 50 * 1024 * 1024) // 50MB限制 { return BadRequest("文件过大,无法下载"); } byte[] fileBytes; using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (MemoryStream memoryStream = new MemoryStream()) { fileStream.CopyTo(memoryStream); fileBytes = memoryStream.ToArray(); } } string contentType = GetContentType(extension); return File(fileBytes, contentType, fileName); } catch (UnauthorizedAccessException) { return StatusCode(403, "没有访问该文件的权限"); } catch (PathTooLongException) { return BadRequest("文件路径过长"); } catch (IOException ex) { return StatusCode(500, "文件读取失败,可能正在被其他进程使用"); } catch (Exception ex) { return StatusCode(500, $"服务器内部错误: {ex.Message}"); } } private bool IsAllowedFileType(string extension) { var allowedTypes = new[] { ".txt", ".log", ".csv", ".json", ".xml" }; return allowedTypes.Contains(extension); } private string GetContentType(string extension) { return extension.ToLowerInvariant() switch { ".txt" => "text/plain; charset=utf-8", ".log" => "text/plain; charset=utf-8", ".csv" => "text/csv; charset=utf-8", ".json" => "application/json; charset=utf-8", ".xml" => "application/xml; charset=utf-8", _ => "application/octet-stream" }; } } }