Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class JsonFileDashboardService : IDashboardService
private readonly DashboardOptions _options;
private readonly IEnumerable<IWidgetDataSource> _dataSources;
private readonly ILogger<JsonFileDashboardService> _logger;
private readonly TimeProvider _timeProvider;
private readonly ConcurrentDictionary<string, DashboardSummary> _index = new();
private readonly ConcurrentDictionary<string, SemaphoreSlim> _locks = new();
private readonly string _baseDir;
Expand All @@ -26,11 +27,13 @@ public class JsonFileDashboardService : IDashboardService
public JsonFileDashboardService(
IOptions<DashboardOptions> options,
IEnumerable<IWidgetDataSource> dataSources,
ILogger<JsonFileDashboardService> logger)
ILogger<JsonFileDashboardService> logger,
TimeProvider? timeProvider = null)
{
_options = options.Value;
_dataSources = dataSources;
_logger = logger;
_timeProvider = timeProvider ?? TimeProvider.System;
_baseDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _options.DashboardDirectory);

logger.LogWarning(
Expand Down Expand Up @@ -184,7 +187,7 @@ public async Task<string> CreateAsync(DashboardDefinition dashboard)
dashboard.Id = Guid.NewGuid().ToString("N");
}

dashboard.CreatedAt = DateTime.UtcNow;
dashboard.CreatedAt = _timeProvider.GetUtcNow().UtcDateTime;
dashboard.UpdatedAt = dashboard.CreatedAt;

var path = GetFilePath(dashboard.Id, dashboard.TenantId);
Expand Down Expand Up @@ -241,7 +244,7 @@ public async Task UpdateAsync(DashboardDefinition dashboard)
throw new ArgumentException("Dashboard ID cannot be null or empty.", nameof(dashboard));
}

dashboard.UpdatedAt = DateTime.UtcNow;
dashboard.UpdatedAt = _timeProvider.GetUtcNow().UtcDateTime;

var path = GetFilePath(dashboard.Id, dashboard.TenantId);
var lockObj = GetLock(dashboard.Id);
Expand Down
9 changes: 7 additions & 2 deletions src/WalkingTec.Mvvm.Core/DataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
// public DbSet<Elsa_WorkflowExecutionLogRecord> Elsa_WorkflowExecutionLogRecords { get; set; }
// public DbSet<Elsa_WorkflowInstance> Elsa_WorkflowInstances { get; set; }
public DbSet<RefreshTokenEntity> FrameworkRefreshTokens { get; set; } = null!;
public DbSet<AnalysisSavedQuery> AnalysisSavedQueries { get; set; } = null!;

Check warning on line 57 in src/WalkingTec.Mvvm.Core/DataContext.cs

View workflow job for this annotation

GitHub Actions / build-and-test

'FrameworkContext.AnalysisSavedQueries' hides inherited member 'EmptyContext.AnalysisSavedQueries'. Use the new keyword if hiding was intended.

/// <summary>
/// FrameworkContext
Expand Down Expand Up @@ -448,6 +448,11 @@

public DBTypeEnum DBType { get; set; }

/// <summary>
/// 可測試的時間來源。預設 TimeProvider.System。
/// </summary>
public TimeProvider TimeProvider { get; set; } = TimeProvider.System;

public string? Version { get; set; }
public CS ConnectionString { get; set; } = null!;
public DbSet<AnalysisSavedQuery> AnalysisSavedQueries { get; set; } = null!;
Expand Down Expand Up @@ -879,14 +884,14 @@
{
case EntityState.Added:
if (entity.CreateTime == null)
entity.CreateTime = DateTime.Now;
entity.CreateTime = TimeProvider.GetLocalNow().DateTime;
if (string.IsNullOrEmpty(entity.CreateBy))
entity.CreateBy = CurrentUserCode;
break;

case EntityState.Modified:
if (entity.UpdateTime == null)
entity.UpdateTime = DateTime.Now;
entity.UpdateTime = TimeProvider.GetLocalNow().DateTime;
if (string.IsNullOrEmpty(entity.UpdateBy))
entity.UpdateBy = CurrentUserCode;
break;
Expand Down
67 changes: 30 additions & 37 deletions src/WalkingTec.Mvvm.Core/Support/DateRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,59 +276,52 @@ public static DateRange Yesterday

public static DateRange UtcDefault => UtcToday;

public static DateRange UtcNinetyDays
/// <summary>UTC 過去 90 天。</summary>
public static DateRange UtcNinetyDays => CreateUtcNinetyDays();
public static DateRange CreateUtcNinetyDays(TimeProvider? timeProvider = null)
{
get
{
var result = new DateRange(DateTime.UtcNow.Date.AddDays(-90), DateTime.UtcNow.Date);
return result;
}
var today = (timeProvider ?? TimeProvider.System).GetUtcNow().UtcDateTime.Date;
return new DateRange(today.AddDays(-90), today);
}

public static DateRange UtcThirtyDays
/// <summary>UTC 過去 30 天。</summary>
public static DateRange UtcThirtyDays => CreateUtcThirtyDays();
public static DateRange CreateUtcThirtyDays(TimeProvider? timeProvider = null)
{
get
{
var result = new DateRange(DateTime.UtcNow.Date.AddDays(-30), DateTime.UtcNow.Date, DefaultType, UtCDefaultEpoch);
return result;
}
var today = (timeProvider ?? TimeProvider.System).GetUtcNow().UtcDateTime.Date;
return new DateRange(today.AddDays(-30), today, DefaultType, UtCDefaultEpoch);
}

public static DateRange UtcTwoWeek
/// <summary>UTC 過去 14 天。</summary>
public static DateRange UtcTwoWeek => CreateUtcTwoWeek();
public static DateRange CreateUtcTwoWeek(TimeProvider? timeProvider = null)
{
get
{
var result = new DateRange(DateTime.UtcNow.Date.AddDays(-14), DateTime.UtcNow.Date, DefaultType, UtCDefaultEpoch);
return result;
}
var today = (timeProvider ?? TimeProvider.System).GetUtcNow().UtcDateTime.Date;
return new DateRange(today.AddDays(-14), today, DefaultType, UtCDefaultEpoch);
}

public static DateRange UtcWeek
/// <summary>UTC 過去 7 天。</summary>
public static DateRange UtcWeek => CreateUtcWeek();
public static DateRange CreateUtcWeek(TimeProvider? timeProvider = null)
{
get
{
var result = new DateRange(DateTime.UtcNow.Date.AddDays(-7), DateTime.UtcNow.Date, DefaultType, UtCDefaultEpoch);
return result;
}

var today = (timeProvider ?? TimeProvider.System).GetUtcNow().UtcDateTime.Date;
return new DateRange(today.AddDays(-7), today, DefaultType, UtCDefaultEpoch);
}

public static DateRange UtcToday
/// <summary>UTC 昨天到今天。</summary>
public static DateRange UtcToday => CreateUtcToday();
public static DateRange CreateUtcToday(TimeProvider? timeProvider = null)
{
get
{
var result = new DateRange(DateTime.UtcNow.Date.AddDays(-1), DateTime.UtcNow.Date, DefaultType, UtCDefaultEpoch);
return result;
}
var today = (timeProvider ?? TimeProvider.System).GetUtcNow().UtcDateTime.Date;
return new DateRange(today.AddDays(-1), today, DefaultType, UtCDefaultEpoch);
}

public static DateRange UtcYesterday
/// <summary>UTC 昨天。</summary>
public static DateRange UtcYesterday => CreateUtcYesterday();
public static DateRange CreateUtcYesterday(TimeProvider? timeProvider = null)
{
get
{
var result = new DateRange(DateTime.UtcNow.Date.AddDays(-1), DateTime.UtcNow.Date, DefaultType, UtCDefaultEpoch);
return result;
}
var today = (timeProvider ?? TimeProvider.System).GetUtcNow().UtcDateTime.Date;
return new DateRange(today.AddDays(-1), today, DefaultType, UtCDefaultEpoch);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public IWtmFile UploadToDB(string fileName, long fileLength, Stream data, strin
FileAttachment file = new FileAttachment();
file.FileName = fileName;
file.Length = fileLength;
file.UploadTime = DateTime.Now;
file.UploadTime = wtm.TimeProvider.GetLocalNow().DateTime;
file.SaveMode = _modeName;
file.ExtraInfo = extra;
file.TenantCode = wtm.LoginUserInfo?.CurrentTenant;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public IWtmFileHandler CreateFileHandler(string? saveMode = null, IDataContext?
FileAttachment file = new FileAttachment();
file.FileName = fileName;
file.Length = fileLength;
file.UploadTime = DateTime.Now;
file.UploadTime = _wtm.TimeProvider.GetLocalNow().DateTime;
file.SaveMode = string.IsNullOrEmpty(saveMode) == true ? _wtm.ConfigInfo.FileUploadOptions.SaveFileMode! : saveMode;
file.ExtraInfo = extra;
var ext = string.Empty;
Expand Down
5 changes: 3 additions & 2 deletions src/WalkingTec.Mvvm.Core/Support/WTMLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,12 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
ll = ActionLogTypesEnum.Exception;
}

var now = (sp.GetService<TimeProvider>() ?? TimeProvider.System).GetLocalNow().DateTime;
log = new ActionLog
{
Remark = formatter?.Invoke(state, exception),
CreateTime = DateTime.Now,
ActionTime = DateTime.Now,
CreateTime = now,
ActionTime = now,
ActionName = "WtmLog",
ModuleName = "WtmLog",
LogType = ll
Expand Down
12 changes: 6 additions & 6 deletions src/WalkingTec.Mvvm.Etl/Scheduling/EtlQuartzJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public override async Task Execute(IJobExecutionContext context)
JobId = jobDefId,
Trigger = trigger,
Result = EtlRunResult.Skipped,
StartedAt = DateTime.UtcNow,
FinishedAt = DateTime.UtcNow
StartedAt = Wtm.TimeProvider.GetUtcNow().UtcDateTime,
FinishedAt = Wtm.TimeProvider.GetUtcNow().UtcDateTime
});

await dc.SaveChangesAsync();
Expand All @@ -71,7 +71,7 @@ public override async Task Execute(IJobExecutionContext context)
dc.Set<EtlJobDefinition>().Update(jobDef);
await dc.SaveChangesAsync();

var startedAt = DateTime.UtcNow;
var startedAt = Wtm.TimeProvider.GetUtcNow().UtcDateTime;

// 建立超時 CancellationToken(連結 Quartz 的 CancellationToken 以支援中止)
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(context.CancellationToken);
Expand Down Expand Up @@ -140,7 +140,7 @@ public override async Task Execute(IJobExecutionContext context)
if (result.Success)
{
jobDef.LastWatermarkValue = result.NewWatermarkValue;
jobDef.LastRunAt = DateTime.UtcNow;
jobDef.LastRunAt = Wtm.TimeProvider.GetUtcNow().UtcDateTime;
jobDef.LastError = null;
jobDef.Status = EtlJobStatus.Enabled;
jobDef.ConsecutiveFailureCount = 0; // reset on success
Expand All @@ -164,7 +164,7 @@ public override async Task Execute(IJobExecutionContext context)
{
Success = false,
ErrorMessage = sanitized,
ElapsedMs = (long)(DateTime.UtcNow - startedAt).TotalMilliseconds
ElapsedMs = (long)(Wtm.TimeProvider.GetUtcNow().UtcDateTime - startedAt).TotalMilliseconds
};

var currentAttempt = context.MergedJobDataMap.ContainsKey("_retryAttempt")
Expand Down Expand Up @@ -207,7 +207,7 @@ public override async Task Execute(IJobExecutionContext context)
ElapsedMs = result?.ElapsedMs ?? 0,
ErrorMessage = result?.ErrorMessage,
StartedAt = startedAt,
FinishedAt = DateTime.UtcNow,
FinishedAt = Wtm.TimeProvider.GetUtcNow().UtcDateTime,
WatermarkSnapshot = jobDef.LastWatermarkValue
};
dc.Set<EtlRunLog>().Add(runLog);
Expand Down
2 changes: 1 addition & 1 deletion src/WalkingTec.Mvvm.Etl/Scheduling/EtlSchedulerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public async Task ResetGhostRunningJobsAsync()

if (ghostJobs.Count == 0) return;

var now = DateTime.UtcNow;
var now = (_sp.GetService<TimeProvider>() ?? TimeProvider.System).GetUtcNow().UtcDateTime;
foreach (var job in ghostJobs)
{
job.Status = EtlJobStatus.Failed;
Expand Down
4 changes: 2 additions & 2 deletions src/WalkingTec.Mvvm.Mvc/Filters/FrameworkFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ public override void OnResultExecuted(ResultExecutedContext context)
var postDes = ctrlActDesc.MethodInfo.GetCustomAttributes(typeof(HttpPostAttribute), false).Cast<HttpPostAttribute>().FirstOrDefault();

log.LogType = context.Exception == null ? ActionLogTypesEnum.Normal : ActionLogTypesEnum.Exception;
log.ActionTime = ctrl.Wtm?.TimeProvider.GetLocalNow().DateTime ?? DateTime.Now;
log.ActionTime = (ctrl.Wtm?.TimeProvider ?? TimeProvider.System).GetLocalNow().DateTime;
log.ITCode = ctrl.Wtm?.LoginUserInfo?.ITCode ?? string.Empty;
// 给日志的多语言属性赋值
log.ModuleName = ctrlDes?.GetDescription(ctrl) ?? ctrlActDesc.ControllerName;
Expand All @@ -392,7 +392,7 @@ public override void OnResultExecuted(ResultExecutedContext context)
var starttime = context.HttpContext.Items["actionstarttime"] as DateTime?;
if (starttime != null)
{
log.Duration = (ctrl.Wtm?.TimeProvider.GetLocalNow().DateTime ?? DateTime.Now).Subtract(starttime.Value).TotalSeconds;
log.Duration = (ctrl.Wtm?.TimeProvider ?? TimeProvider.System).GetLocalNow().DateTime.Subtract(starttime.Value).TotalSeconds;
}
try
{
Expand Down
Loading