新增 OTA WatchDog 编排与车队健康/报警后端。
覆盖包库回传、任务下发、CDM 任务同步与报警采集,并为包/任务 ID 与上传文件名加上路径安全校验。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
namespace MiGu.Server.Ota;
|
||||
|
||||
public sealed class OtaSettings
|
||||
{
|
||||
public int BandwidthKbps { get; set; }
|
||||
public int MaxCar { get; set; } = 2;
|
||||
public bool LatencyEnabled { get; set; }
|
||||
public int RttThresholdMs { get; set; } = 200;
|
||||
/// <summary>skip | confirm</summary>
|
||||
public string OverThreshold { get; set; } = "skip";
|
||||
public int BackupPeriodMinutes { get; set; } = 60;
|
||||
public bool BackupExe { get; set; }
|
||||
public string? NewVersionName { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaFileArtifact
|
||||
{
|
||||
public string Hash { get; set; } = "";
|
||||
public string Path { get; set; } = "";
|
||||
public string FileName { get; set; } = "";
|
||||
public string? Time { get; set; }
|
||||
public long Size { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaTarget
|
||||
{
|
||||
public string PackageId { get; set; } = "";
|
||||
public string? Name { get; set; }
|
||||
public DateTimeOffset ActivatedAt { get; set; }
|
||||
public Dictionary<string, OtaFileArtifact> Components { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public sealed class OtaPackageInfo
|
||||
{
|
||||
public string Id { get; set; } = "";
|
||||
public string? SourceIp { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public long TotalBytes { get; set; }
|
||||
public bool IsTarget { get; set; }
|
||||
public Dictionary<string, OtaFileArtifact> Components { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public sealed class OtaComponentVersion
|
||||
{
|
||||
public string? Version { get; set; }
|
||||
public string? Time { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaAppVersions
|
||||
{
|
||||
public OtaComponentVersion? Exe { get; set; }
|
||||
public OtaComponentVersion? Dll { get; set; }
|
||||
public OtaComponentVersion? Pdb { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaVehicleRow
|
||||
{
|
||||
public string Id { get; set; } = "";
|
||||
public string Name { get; set; } = "";
|
||||
public string? Ip { get; set; }
|
||||
public string? State { get; set; }
|
||||
public string? Group { get; set; }
|
||||
public bool Reachable { get; set; }
|
||||
public int? RttMs { get; set; }
|
||||
public OtaAppVersions? Medulla { get; set; }
|
||||
public OtaAppVersions? Detour { get; set; }
|
||||
public OtaAppVersions? Clumsy { get; set; }
|
||||
public Dictionary<string, string>? Match { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaJobStep
|
||||
{
|
||||
public string CarId { get; set; } = "";
|
||||
public string? Ip { get; set; }
|
||||
public string Component { get; set; } = "";
|
||||
public string Status { get; set; } = "pending";
|
||||
public string? Error { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaJob
|
||||
{
|
||||
public string Id { get; set; } = "";
|
||||
/// <summary>sync | customFile | configPush</summary>
|
||||
public string Kind { get; set; } = "sync";
|
||||
public string Status { get; set; } = "pending";
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? FinishedAt { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public string? PackageId { get; set; }
|
||||
public List<string> CarIds { get; set; } = new();
|
||||
public List<string> Components { get; set; } = new();
|
||||
public bool RequireLatencyCheck { get; set; }
|
||||
public int DoneSteps { get; set; }
|
||||
public int TotalSteps { get; set; }
|
||||
public List<OtaJobStep> Steps { get; set; } = new();
|
||||
public string? Message { get; set; }
|
||||
// customFile
|
||||
public string? CustomFileName { get; set; }
|
||||
public string? CustomRemotePath { get; set; }
|
||||
public int? CustomRestartOp { get; set; }
|
||||
public string? CustomLocalPath { get; set; }
|
||||
public List<OtaCustomFileItem> CustomFiles { get; set; } = new();
|
||||
public List<int> CustomRestartOps { get; set; } = new() { -1 };
|
||||
// configPush
|
||||
public string? ConfigApp { get; set; }
|
||||
public string? ConfigJson { get; set; }
|
||||
}
|
||||
|
||||
public sealed class CreateSyncJobRequest
|
||||
{
|
||||
public List<string> CarIds { get; set; } = new();
|
||||
public List<string>? Components { get; set; }
|
||||
public bool? RequireLatencyCheck { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PullPackageRequest
|
||||
{
|
||||
public string CarId { get; set; } = "";
|
||||
}
|
||||
|
||||
public sealed class CreateCustomFileJobRequest
|
||||
{
|
||||
public List<string> CarIds { get; set; } = new();
|
||||
public string RemotePath { get; set; } = "";
|
||||
/// <summary>兼容旧单值;优先用 RestartOps。</summary>
|
||||
public int RestartOp { get; set; } = -1;
|
||||
/// <summary>-1 不重启;0 Medulla;1 Clumsy;2 Detour;3 WatchDog。可多选。</summary>
|
||||
public List<int>? RestartOps { get; set; }
|
||||
public bool? RequireLatencyCheck { get; set; }
|
||||
}
|
||||
|
||||
public sealed class OtaCustomFileItem
|
||||
{
|
||||
public string LocalPath { get; set; } = "";
|
||||
public string FileName { get; set; } = "";
|
||||
}
|
||||
|
||||
public sealed class CreateConfigPushRequest
|
||||
{
|
||||
public List<string> CarIds { get; set; } = new();
|
||||
public string App { get; set; } = "";
|
||||
public string Json { get; set; } = "";
|
||||
public bool? RequireLatencyCheck { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user