fix
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 24s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 3s
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 24s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 3s
This commit is contained in:
@@ -94,7 +94,7 @@ public class BaseResponse<T> : BaseResponse
|
||||
/// 返回数据
|
||||
/// </summary>
|
||||
public T? Data { get; set; }
|
||||
|
||||
|
||||
public new static BaseResponse<T> Fail(string message)
|
||||
{
|
||||
return new BaseResponse<T>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
public class PagedResponse<T> : BaseResponse<T[]>
|
||||
{
|
||||
public long LastId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 最后一条记录的时间(用于游标分页)
|
||||
/// </summary>
|
||||
@@ -13,7 +13,7 @@ public class PagedResponse<T> : BaseResponse<T[]>
|
||||
/// 总记录数
|
||||
/// </summary>
|
||||
public int Total { get; set; }
|
||||
|
||||
|
||||
public new static PagedResponse<T> Fail(string message)
|
||||
{
|
||||
return new PagedResponse<T>
|
||||
|
||||
@@ -21,7 +21,7 @@ public class JobController(ISchedulerFactory schedulerFactory, ILogger<JobContro
|
||||
var jobDetail = await scheduler.GetJobDetail(jobKey);
|
||||
var triggers = await scheduler.GetTriggersOfJob(jobKey);
|
||||
var trigger = triggers.FirstOrDefault();
|
||||
|
||||
|
||||
var status = "Unknown";
|
||||
DateTime? nextFireTime = null;
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ public class LogController(ILogger<LogController> logger) : ControllerBase
|
||||
/// <summary>
|
||||
/// 获取日志列表(分页)
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<PagedResponse<LogEntry>> GetListAsync(
|
||||
[FromQuery] int pageIndex = 1,
|
||||
[FromQuery] int pageSize = 50,
|
||||
[FromQuery] string? searchKeyword = null,
|
||||
[FromQuery] string? logLevel = null,
|
||||
[FromQuery] string? date = null,
|
||||
[FromQuery] string? className = null
|
||||
)
|
||||
[HttpGet]
|
||||
public async Task<PagedResponse<LogEntry>> GetListAsync(
|
||||
[FromQuery] int pageIndex = 1,
|
||||
[FromQuery] int pageSize = 50,
|
||||
[FromQuery] string? searchKeyword = null,
|
||||
[FromQuery] string? logLevel = null,
|
||||
[FromQuery] string? date = null,
|
||||
[FromQuery] string? className = null
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -221,7 +221,7 @@ public async Task<PagedResponse<LogEntry>> GetListAsync(
|
||||
logger.LogError(ex, "获取类名列表失败");
|
||||
return $"获取类名列表失败: {ex.Message}".Fail<string[]>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并多行日志(已废弃,现在在流式读取中处理)
|
||||
@@ -385,27 +385,27 @@ public async Task<PagedResponse<LogEntry>> GetListAsync(
|
||||
/// <summary>
|
||||
/// 读取日志
|
||||
/// </summary>
|
||||
private async Task<(List<LogEntry> entries, int total)> ReadLogsAsync(
|
||||
string path,
|
||||
int pageIndex,
|
||||
int pageSize,
|
||||
string? searchKeyword,
|
||||
string? logLevel,
|
||||
string? className)
|
||||
{
|
||||
var allLines = await ReadAllLinesAsync(path);
|
||||
|
||||
var merged = MergeMultiLineLog(allLines);
|
||||
|
||||
var parsed = new List<LogEntry>();
|
||||
foreach (var line in merged)
|
||||
private async Task<(List<LogEntry> entries, int total)> ReadLogsAsync(
|
||||
string path,
|
||||
int pageIndex,
|
||||
int pageSize,
|
||||
string? searchKeyword,
|
||||
string? logLevel,
|
||||
string? className)
|
||||
{
|
||||
var entry = ParseLogLine(line);
|
||||
if (entry != null && PassFilter(entry, searchKeyword, logLevel, className))
|
||||
var allLines = await ReadAllLinesAsync(path);
|
||||
|
||||
var merged = MergeMultiLineLog(allLines);
|
||||
|
||||
var parsed = new List<LogEntry>();
|
||||
foreach (var line in merged)
|
||||
{
|
||||
parsed.Add(entry);
|
||||
var entry = ParseLogLine(line);
|
||||
if (entry != null && PassFilter(entry, searchKeyword, logLevel, className))
|
||||
{
|
||||
parsed.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parsed.Reverse();
|
||||
|
||||
@@ -419,28 +419,28 @@ private async Task<(List<LogEntry> entries, int total)> ReadLogsAsync(
|
||||
/// <summary>
|
||||
/// 检查日志条目是否通过过滤条件
|
||||
/// </summary>
|
||||
private bool PassFilter(LogEntry logEntry, string? searchKeyword, string? logLevel, string? className)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchKeyword) &&
|
||||
!logEntry.Message.Contains(searchKeyword, StringComparison.OrdinalIgnoreCase))
|
||||
private bool PassFilter(LogEntry logEntry, string? searchKeyword, string? logLevel, string? className)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(searchKeyword) &&
|
||||
!logEntry.Message.Contains(searchKeyword, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(logLevel) &&
|
||||
!logEntry.Level.Equals(logLevel, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(logLevel) &&
|
||||
!logEntry.Level.Equals(logLevel, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(className) &&
|
||||
!logEntry.ClassName.Equals(className, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(className) &&
|
||||
!logEntry.ClassName.Equals(className, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取文件所有行(支持共享读取)
|
||||
|
||||
@@ -32,7 +32,7 @@ public class NotificationController(INotificationService notificationService) :
|
||||
return ex.Message.Fail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<BaseResponse> TestNotification([FromQuery] string message)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -26,7 +26,7 @@ public class TransactionCategoryController(
|
||||
{
|
||||
categories = (await categoryRepository.GetAllAsync()).ToList();
|
||||
}
|
||||
|
||||
|
||||
return categories.Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -38,18 +38,18 @@ public class TransactionRecordController(
|
||||
: classify.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
TransactionType? transactionType = type.HasValue ? (TransactionType)type.Value : null;
|
||||
var list = await transactionRepository.QueryAsync(
|
||||
year: year,
|
||||
month: month,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
type: transactionType,
|
||||
classifies: classifies,
|
||||
searchKeyword: searchKeyword,
|
||||
reason: reason,
|
||||
pageIndex: pageIndex,
|
||||
pageSize: pageSize,
|
||||
sortByAmount: sortByAmount);
|
||||
var list = await transactionRepository.QueryAsync(
|
||||
year: year,
|
||||
month: month,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
type: transactionType,
|
||||
classifies: classifies,
|
||||
searchKeyword: searchKeyword,
|
||||
reason: reason,
|
||||
pageIndex: pageIndex,
|
||||
pageSize: pageSize,
|
||||
sortByAmount: sortByAmount);
|
||||
var total = await transactionRepository.CountAsync(
|
||||
year: year,
|
||||
month: month,
|
||||
@@ -214,6 +214,12 @@ var list = await transactionRepository.QueryAsync(
|
||||
transaction.Type = dto.Type;
|
||||
transaction.Classify = dto.Classify ?? string.Empty;
|
||||
|
||||
// 更新交易时间
|
||||
if (!string.IsNullOrEmpty(dto.OccurredAt) && DateTime.TryParse(dto.OccurredAt, out var occurredAt))
|
||||
{
|
||||
transaction.OccurredAt = occurredAt;
|
||||
}
|
||||
|
||||
// 清除待确认状态
|
||||
transaction.UnconfirmedClassify = null;
|
||||
transaction.UnconfirmedType = null;
|
||||
@@ -272,7 +278,7 @@ var list = await transactionRepository.QueryAsync(
|
||||
|
||||
// 获取每日统计数据
|
||||
var statistics = await transactionStatisticsService.GetDailyStatisticsAsync(year, month, savingClassify);
|
||||
|
||||
|
||||
// 按日期排序并计算累积余额
|
||||
var sortedStats = statistics.OrderBy(s => s.Key).ToList();
|
||||
var result = new List<BalanceStatisticsDto>();
|
||||
@@ -693,7 +699,7 @@ var list = await transactionRepository.QueryAsync(
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WriteEventAsync(string eventType, string data)
|
||||
private async Task WriteEventAsync(string eventType, string data)
|
||||
{
|
||||
var message = $"event: {eventType}\ndata: {data}\n\n";
|
||||
await Response.WriteAsync(message);
|
||||
@@ -728,7 +734,8 @@ public record UpdateTransactionDto(
|
||||
decimal Amount,
|
||||
decimal Balance,
|
||||
TransactionType Type,
|
||||
string? Classify
|
||||
string? Classify,
|
||||
string? OccurredAt = null
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -14,9 +14,9 @@ public class RequestIdMiddleware
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var requestId = context.Request.Headers["X-Request-ID"].FirstOrDefault() ?? Guid.NewGuid().ToString("N");
|
||||
|
||||
|
||||
context.Items["RequestId"] = requestId;
|
||||
|
||||
|
||||
using (LogContext.PushProperty("RequestId", requestId))
|
||||
{
|
||||
await _next(context);
|
||||
@@ -30,7 +30,7 @@ public static class RequestIdExtensions
|
||||
{
|
||||
return context.Items["RequestId"] as string;
|
||||
}
|
||||
|
||||
|
||||
public static IApplicationBuilder UseRequestId(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<RequestIdMiddleware>();
|
||||
|
||||
@@ -110,7 +110,7 @@ var fsql = new FreeSqlBuilder()
|
||||
.UseAutoSyncStructure(true)
|
||||
.UseLazyLoading(true)
|
||||
.UseMonitorCommand(
|
||||
cmd =>
|
||||
cmd =>
|
||||
{
|
||||
Log.Verbose("执行SQL: {Sql}", cmd.CommandText);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user