初始化
Some checks failed
CI/CD Pipeline / 测试 (18.x) (push) Has been cancelled
CI/CD Pipeline / 测试 (20.x) (push) Has been cancelled
CI/CD Pipeline / 安全检查 (push) Has been cancelled
CI/CD Pipeline / 部署 (push) Has been cancelled
CI/CD Pipeline / 通知 (push) Has been cancelled

This commit is contained in:
2025-11-03 19:47:36 +08:00
parent 7a04b85667
commit f25b0307db
454 changed files with 37064 additions and 4544 deletions

View File

@@ -0,0 +1,151 @@
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace HardwarePerformanceAPI.Controllers
{
[ApiController]
[Route("api/monitor")]
public class MonitorController : ControllerBase
{
private readonly ILogger<MonitorController> _logger;
private readonly string _logDirectory;
public MonitorController(ILogger<MonitorController> logger)
{
_logger = logger;
// 设置日志存储目录
_logDirectory = Path.Combine(Directory.GetCurrentDirectory(), "logs", "monitor");
// 确保目录存在
if (!Directory.Exists(_logDirectory))
{
Directory.CreateDirectory(_logDirectory);
}
}
[HttpPost("report")]
public async Task<IActionResult> ReportData([FromBody] JsonElement data)
{
try
{
// 获取客户端IP
var clientIp = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
// 获取用户代理
var userAgent = Request.Headers["User-Agent"].ToString() ?? "unknown";
// 添加元数据
var reportData = new
{
Timestamp = DateTime.UtcNow,
ClientIp = clientIp,
UserAgent = userAgent,
Data = data
};
// 生成文件名(按日期分类)
var fileName = $"monitor_{DateTime.UtcNow:yyyyMMdd}.json";
var filePath = Path.Combine(_logDirectory, fileName);
// 将数据写入文件
var json = JsonSerializer.Serialize(reportData, new JsonSerializerOptions
{
WriteIndented = true
});
await System.IO.File.AppendAllTextAsync(filePath, json + Environment.NewLine + Environment.NewLine);
_logger.LogInformation("Monitor data received from {ClientIp}", clientIp);
return Ok(new { success = true, message = "Data reported successfully" });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing monitor data");
return StatusCode(500, new { success = false, message = "Internal server error" });
}
}
[HttpGet("stats")]
public IActionResult GetStats()
{
try
{
var stats = new
{
ReportsCount = CountReports(),
LastReportTime = GetLastReportTime(),
ErrorCount = CountReportsByType("error"),
PerformanceCount = CountReportsByType("performance")
};
return Ok(stats);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting monitor stats");
return StatusCode(500, new { success = false, message = "Internal server error" });
}
}
private int CountReports()
{
var today = DateTime.UtcNow.ToString("yyyyMMdd");
var filePath = Path.Combine(_logDirectory, $"monitor_{today}.json");
if (!System.IO.File.Exists(filePath))
return 0;
var content = System.IO.File.ReadAllText(filePath);
var lines = content.Split(new[] { Environment.NewLine + Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
return lines.Length;
}
private DateTime? GetLastReportTime()
{
var today = DateTime.UtcNow.ToString("yyyyMMdd");
var filePath = Path.Combine(_logDirectory, $"monitor_{today}.json");
if (!System.IO.File.Exists(filePath))
return null;
var fileInfo = new FileInfo(filePath);
return fileInfo.LastWriteTimeUtc;
}
private int CountReportsByType(string type)
{
var today = DateTime.UtcNow.ToString("yyyyMMdd");
var filePath = Path.Combine(_logDirectory, $"monitor_{today}.json");
if (!System.IO.File.Exists(filePath))
return 0;
var content = System.IO.File.ReadAllText(filePath);
var lines = content.Split(new[] { Environment.NewLine + Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
int count = 0;
foreach (var line in lines)
{
try
{
using var document = JsonDocument.Parse(line);
if (document.RootElement.TryGetProperty("Data", out var dataElement))
{
if (dataElement.TryGetProperty("type", out var typeElement) &&
typeElement.GetString()?.Contains(type) == true)
{
count++;
}
}
}
catch
{
// 忽略解析错误
}
}
return count;
}
}
}

View File

@@ -68,87 +68,32 @@ public class TestController : ControllerBase
}
[HttpGet("categories")]
public async Task<IActionResult> GetCategories()
{
try
public async Task<IActionResult> GetCategories()
{
var categories = new List<object>();
using var connection = new MySql.Data.MySqlClient.MySqlConnection(
"Server=localhost;Database=HardwarePerformance;User=root;Password=123456;");
await connection.OpenAsync();
using var cmd = new MySql.Data.MySqlClient.MySqlCommand("SELECT * FROM Categories", connection);
using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
try
{
categories.Add(new
{
Id = reader.GetInt32("Id"),
Name = reader.GetString("Name"),
Description = reader.IsDBNull("Description") ? null : reader.GetString("Description"),
CreatedAt = reader.GetDateTime("CreatedAt")
});
var categories = await _context.GetCategoriesAsync();
return Ok(new { success = true, data = categories });
}
return Ok(categories);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取类别列表时发生错误");
return StatusCode(500, new
catch (Exception ex)
{
Message = $"获取类别列表时发生错误: {ex.Message}",
Timestamp = DateTime.Now
});
_logger.LogError(ex, "获取类别列表时发生错误");
return StatusCode(500, new { success = false, message = ex.Message });
}
}
}
[HttpGet("products")]
public async Task<IActionResult> GetProducts()
{
try
public async Task<IActionResult> GetProducts([FromQuery] int categoryId = 0, [FromQuery] int page = 1, [FromQuery] int pageSize = 10)
{
var products = new List<object>();
using var connection = new MySql.Data.MySqlClient.MySqlConnection(
"Server=localhost;Database=HardwarePerformance;User=root;Password=123456;");
await connection.OpenAsync();
using var cmd = new MySql.Data.MySqlClient.MySqlCommand(
@"SELECT p.*, c.Name as CategoryName
FROM Products p
LEFT JOIN Categories c ON p.CategoryId = c.Id", connection);
using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
try
{
products.Add(new
{
Id = reader.GetInt32("Id"),
Name = reader.GetString("Name"),
Model = reader.IsDBNull("Model") ? null : reader.GetString("Model"),
Manufacturer = reader.IsDBNull("Manufacturer") ? null : reader.GetString("Manufacturer"),
ImageUrl = reader.IsDBNull("ImageUrl") ? null : reader.GetString("ImageUrl"),
ReleaseDate = reader.IsDBNull("ReleaseDate") ? (DateTime?)null : reader.GetDateTime("ReleaseDate"),
CategoryId = reader.IsDBNull("CategoryId") ? (int?)null : reader.GetInt32("CategoryId"),
CategoryName = reader.IsDBNull("CategoryName") ? null : reader.GetString("CategoryName"),
CurrentRank = reader.IsDBNull("CurrentRank") ? (int?)null : reader.GetInt32("CurrentRank"),
CreatedAt = reader.GetDateTime("CreatedAt")
});
var products = await _context.GetProductsAsync(categoryId, page, pageSize);
return Ok(new { success = true, data = products });
}
return Ok(products);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取产品列表时发生错误");
return StatusCode(500, new
catch (Exception ex)
{
Message = $"获取产品列表时发生错误: {ex.Message}",
Timestamp = DateTime.Now
});
_logger.LogError(ex, "获取产品列表时发生错误");
return StatusCode(500, new { success = false, message = ex.Message });
}
}
}
}

View File

@@ -10,7 +10,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="StackExchange.Redis" Version="2.7.10" />
<PackageReference Include="StackExchange.Redis" Version="2.7.27" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
</ItemGroup>

View File

@@ -1,4 +1,7 @@
using System.IO.Compression;
using System.Linq;
using Microsoft.AspNetCore.ResponseCompression;
using StackExchange.Redis;
using HardwarePerformance.Infrastructure.Services;
var builder = WebApplication.CreateBuilder(args);

View File

@@ -0,0 +1,20 @@
{
"runtimeOptions": {
"tfm": "net9.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
},
{
"name": "Microsoft.AspNetCore.App",
"version": "9.0.0"
}
],
"configProperties": {
"System.GC.Server": true,
"System.Reflection.NullabilityInfoContext.IsSupported": true,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

View File

@@ -0,0 +1 @@
{"Version":1,"ManifestType":"Build","Endpoints":[]}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,13 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=HardwarePerformance;User=root;Password=123456;",
"Redis": "localhost:6379"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

Some files were not shown because too many files have changed in this diff Show More