feat: add fnOS packaging, storage workflows and release pipeline

This commit is contained in:
2026-08-11 18:05:49 +08:00
parent c5922f9b08
commit 95932f0199
181 changed files with 24024 additions and 1164 deletions
+5
View File
@@ -24,6 +24,11 @@ namespace dy.net.model.entity
/// </summary>
public int BatchCount { get; set; } = 18;
/// <summary>
/// 新同步任务使用的全局存储。历史记录始终使用自身保存的存储类型。
/// </summary>
public dy.net.model.dto.StorageType StorageType { get; set; } = dy.net.model.dto.StorageType.Local;
/// <summary>
/// 博主视频是否 直接用标题做文件名
/// </summary>
+46
View File
@@ -145,5 +145,51 @@ namespace dy.net.model.entity
/// </summary>
[SugarColumn(Length = 500, IsNullable = true)]
public string SeriesPath { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string WebDavCollectPath { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string WebDavFavoritePath { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string WebDavFollowPath { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string WebDavMixPath { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string WebDavSeriesPath { get; set; }
public int ConsecutiveSourceForbidden { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? SourceCooldownUntil { get; set; }
public bool SourceRequiresAuthorization { get; set; }
public bool SourceProbePending { get; set; }
public bool SourceProbeInProgress { get; set; }
[SugarColumn(IsNullable = true)]
public int? LastSourceStatusCode { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string LastSourceError { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? SourceHealthUpdatedAt { get; set; }
public int ConsecutiveLiveCheckFailures { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LiveCheckCooldownUntil { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string LastLiveCheckError { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LiveCheckHealthUpdatedAt { get; set; }
}
}
+54 -1
View File
@@ -1,4 +1,5 @@
using SqlSugar;
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
@@ -72,5 +73,57 @@ namespace dy.net.model.entity
[SugarColumn(IsNullable = true, Length = 100)]
public string DouyinNo { get; set; }
/// <summary>
/// 直播状态监测独立开关,不影响作品同步开关。
/// </summary>
public bool LiveMonitorEnabled { get; set; }
public DouyinLiveStatusState LiveStatus { get; set; }
[SugarColumn(IsNullable = true, Length = 100)]
public string LiveRoomId { get; set; }
[SugarColumn(IsNullable = true, Length = 100)]
public string LiveWebRid { get; set; }
[SugarColumn(IsNullable = true, Length = 500)]
public string LiveTitle { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LiveCheckedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LiveStatusUpdatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LiveStartedAt { get; set; }
[SugarColumn(IsNullable = true, Length = 1000)]
public string LiveCheckError { get; set; }
public bool LiveEmailNotificationEnabled { get; set; }
[SugarColumn(IsNullable = true, Length = 200)]
public string LastLiveNotificationKey { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastLiveNotificationAttemptAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastLiveNotifiedAt { get; set; }
[SugarColumn(IsNullable = true, Length = 1000)]
public string LastLiveNotificationError { get; set; }
[SugarColumn(IsIgnore = true)]
public bool LiveStatusStale => LiveMonitorEnabled &&
(!LiveStatusUpdatedAt.HasValue || DateTime.Now - LiveStatusUpdatedAt.Value > TimeSpan.FromMinutes(10) ||
!string.IsNullOrWhiteSpace(LiveCheckError));
[SugarColumn(IsIgnore = true)]
public string LiveRoomUrl => LiveStatus == DouyinLiveStatusState.Live && !string.IsNullOrWhiteSpace(LiveWebRid)
? "https://live.douyin.com/" + Uri.EscapeDataString(LiveWebRid)
: null;
}
}
+9
View File
@@ -25,6 +25,8 @@ namespace dy.net.model.entity
public string SavePath { get; set; }
public string CookieId { get; set; }
[SugarColumn(IsNullable = true, Length = 100)]
public string VideoRecordId { get; set; }
/// <summary>
/// 0-未下载 1-下载成功 2-下载失败
/// </summary>
@@ -33,5 +35,12 @@ namespace dy.net.model.entity
public DateTime CreateTime { get; set; }
public DateTime DownTime { get; set; }
public DateTime UpdateTime { get; set; }
public int Attempts { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
[SugarColumn(Length = 50, IsNullable = true)]
public string TaskId { get; set; }
[SugarColumn(Length = 50, IsNullable = true)]
public string TaskItemId { get; set; }
}
}
+24
View File
@@ -1,4 +1,5 @@
using dy.net.model.dto;
using MediaStorageType = dy.net.model.dto.StorageType;
using dy.net.utils;
using SqlSugar;
@@ -77,6 +78,11 @@ namespace dy.net.model.entity
/// </summary>
[SugarColumn(Length = 2000, IsNullable = true)]
public string VideoSavePath { get; set; }
/// <summary>
/// 该记录实际所在存储。旧数据默认值 0 表示本地文件。
/// </summary>
public MediaStorageType StorageType { get; set; } = MediaStorageType.Local;
/// <summary>
/// 视频封面地址
/// </summary>
@@ -171,5 +177,23 @@ namespace dy.net.model.entity
/// </summary>
[SugarColumn(Length = 200, IsNullable = true)]
public string CateXId { get; set; }
[SugarColumn(IsIgnore = true)]
public string PendingStoragePath { get; set; }
[SugarColumn(IsIgnore = true)]
public string TemporaryDirectory { get; set; }
[SugarColumn(IsIgnore = true)]
public string TaskItemId { get; set; }
[SugarColumn(IsIgnore = true)]
public string TaskWarning { get; set; }
/// <summary>
/// 普通同步将旧存储记录安全替换到当前存储时使用的旧记录快照,不写入数据库。
/// </summary>
[SugarColumn(IsIgnore = true)]
public DouyinVideo SupersededStorageSnapshot { get; set; }
}
}
+20 -1
View File
@@ -1,4 +1,5 @@
using SqlSugar;
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
@@ -25,5 +26,23 @@ namespace dy.net.model.entity
public string VideoTitle { get; set; }
[SugarColumn(IsNullable = true, Length = 1000)]
public string VideoSavePath { get; set; }
[SugarColumn(IsNullable = true, Length = 200)]
public string CookieId { get; set; }
[SugarColumn(IsNullable = true)]
public VideoTypeEnum? VideoType { get; set; }
[SugarColumn(IsNullable = true, Length = 200)]
public string AuthorId { get; set; }
[SugarColumn(IsNullable = true, Length = 500)]
public string Author { get; set; }
[SugarColumn(IsNullable = true, Length = 2000)]
public string VideoUrl { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string RestoreSnapshotJson { get; set; }
}
}
+42
View File
@@ -0,0 +1,42 @@
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "dy_email_notification_settings")]
public sealed class EmailNotificationSettings
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; } = "default";
public bool Enabled { get; set; }
[SugarColumn(Length = 500, IsNullable = true)]
public string Host { get; set; }
public int Port { get; set; } = 465;
public EmailSecurityMode SecurityMode { get; set; } = EmailSecurityMode.SslOnConnect;
[SugarColumn(Length = 500, IsNullable = true)]
public string UserName { get; set; }
[SugarColumn(Length = -1, IsNullable = true)]
public string ProtectedPassword { get; set; }
[SugarColumn(Length = 500, IsNullable = true)]
public string FromAddress { get; set; }
[SugarColumn(Length = 200, IsNullable = true)]
public string FromName { get; set; }
[SugarColumn(Length = 4000, IsNullable = true)]
public string Recipients { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastTestedAt { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string LastTestMessage { get; set; }
}
}
+25
View File
@@ -0,0 +1,25 @@
using dy.net.model.dto;
using SqlSugar;
using MediaStorageType = dy.net.model.dto.StorageType;
namespace dy.net.model.entity
{
[SugarTable(TableName = "media_storage_health")]
public class MediaStorageHealth
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; } = "default";
public MediaStorageHealthStatus Status { get; set; }
public MediaStorageType StorageType { get; set; }
[SugarColumn(Length = 128, IsNullable = true)]
public string ConfigurationFingerprint { get; set; }
public int ConsecutiveFailures { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string LastError { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastFailedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastProbedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}
@@ -0,0 +1,28 @@
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "openlist_directory_repair_item")]
[SugarIndex("idx_openlist_repair_item_task_status", nameof(TaskId), OrderByType.Asc,
nameof(Status), OrderByType.Asc)]
public sealed class OpenListDirectoryRepairItem
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
[SugarColumn(Length = 50)]
public string TaskId { get; set; }
[SugarColumn(Length = 500)]
public string DirectoryName { get; set; }
[SugarColumn(Length = 2000)]
public string ActualPath { get; set; }
public OpenListDirectoryRepairItemStatus Status { get; set; }
public int Attempts { get; set; }
public int EntryCount { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)] public DateTime? CompletedAt { get; set; }
}
}
@@ -0,0 +1,42 @@
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "openlist_directory_repair_task")]
[SugarIndex("idx_openlist_repair_created", nameof(CreatedAt), OrderByType.Desc)]
public sealed class OpenListDirectoryRepairTask
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
public OpenListDirectoryRepairStatus Status { get; set; }
[SugarColumn(Length = 128)]
public string ConfigurationFingerprint { get; set; }
[SugarColumn(Length = 2000)]
public string RequestedPath { get; set; }
[SugarColumn(Length = 2000)]
public string CanonicalPath { get; set; }
[SugarColumn(Length = 2000)]
public string ActualParentPath { get; set; }
[SugarColumn(Length = 500)]
public string RequestedName { get; set; }
[SugarColumn(Length = 1000)]
public string CandidatePattern { get; set; }
public int TotalCount { get; set; }
public int PendingCount { get; set; }
public int EmptyCount { get; set; }
public int DeletedCount { get; set; }
public int SkippedCount { get; set; }
public int FailedCount { get; set; }
public int MissingCount { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string CurrentDirectory { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
public DateTime CreatedAt { get; set; }
[SugarColumn(IsNullable = true)] public DateTime? StartedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)] public DateTime? ScanCompletedAt { get; set; }
[SugarColumn(IsNullable = true)] public DateTime? CompletedAt { get; set; }
}
}
+41
View File
@@ -0,0 +1,41 @@
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "dy_openlist_settings")]
public class OpenListSettings
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; } = "default";
[SugarColumn(Length = 1000, IsNullable = true)]
public string Endpoint { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string BasePath { get; set; } = "/dysync";
/// <summary>本应用写入中转文件的本地绝对路径。</summary>
[SugarColumn(Length = 1000, IsNullable = true)]
public string LocalStagingPath { get; set; } = string.Empty;
/// <summary>OpenList 中映射到 LocalStagingPath 的源挂载根目录。</summary>
[SugarColumn(Length = 1000, IsNullable = true)]
public string SourcePath { get; set; } = string.Empty;
/// <summary>旧草稿字段,仅用于平滑升级;新版本统一使用 BasePath 作为目标目录。</summary>
[SugarColumn(Length = 1000, IsNullable = true)]
public string DestinationPath { get; set; } = string.Empty;
[SugarColumn(Length = 500, IsNullable = true)]
public string UserName { get; set; }
[SugarColumn(Length = -1, IsNullable = true)]
public string ProtectedPassword { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastTestedAt { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string LastTestMessage { get; set; }
}
}
+50
View File
@@ -0,0 +1,50 @@
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "openlist_transfer_job")]
[SugarIndex("idx_openlist_transfer_target", nameof(ConfigurationFingerprint), OrderByType.Asc,
nameof(LogicalTargetPath), OrderByType.Asc, nameof(Status), OrderByType.Asc)]
public sealed class OpenListTransferJob
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
public OpenListTransferStatus Status { get; set; }
[SugarColumn(Length = 128)]
public string ConfigurationFingerprint { get; set; }
[SugarColumn(Length = 2000)]
public string LogicalTargetPath { get; set; }
[SugarColumn(Length = 2000)]
public string ActualTargetPath { get; set; }
[SugarColumn(Length = 2000)]
public string LocalSourcePath { get; set; }
[SugarColumn(Length = 2000)]
public string OpenListSourcePath { get; set; }
[SugarColumn(Length = 2000)]
public string StagedTargetPath { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string BackupTargetPath { get; set; }
public long ExpectedLength { get; set; }
[SugarColumn(Length = 200, IsNullable = true)]
public string ExternalTaskId { get; set; }
public double ExternalProgress { get; set; }
public int Attempts { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? ExternalTaskStartedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastProgressAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? NextAttemptAt { get; set; }
[SugarColumn(Length = 50, IsNullable = true)]
public string LeaseOwner { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LeaseUntil { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CompletedAt { get; set; }
}
}
+46
View File
@@ -0,0 +1,46 @@
using dy.net.model.dto;
using SqlSugar;
using AppStorageType = dy.net.model.dto.StorageType;
namespace dy.net.model.entity
{
[SugarTable(TableName = "storage_migration_item")]
[SugarIndex("idx_migration_item_task_stage", nameof(TaskId), OrderByType.Asc, nameof(Stage), OrderByType.Asc)]
public class StorageMigrationItem
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
[SugarColumn(Length = 50)]
public string TaskId { get; set; }
[SugarColumn(Length = 200)]
public string VideoId { get; set; }
[SugarColumn(IsNullable = true)]
public AppStorageType? SourceStorageType { get; set; }
public bool AdoptExistingTarget { get; set; }
public StorageMigrationItemStage Stage { get; set; }
public int Attempts { get; set; }
public long ExpectedLength { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string OldVideoPath { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string TargetVideoPath { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string TargetCoverPath { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1)]
public string OldSnapshotJson { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string AttachmentPlanJson { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string UploadedPathsJson { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string OwnedRemotePathsJson { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string WarningMessage { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CompletedAt { get; set; }
}
}
+46
View File
@@ -0,0 +1,46 @@
using dy.net.model.dto;
using SqlSugar;
using AppStorageType = dy.net.model.dto.StorageType;
namespace dy.net.model.entity
{
[SugarTable(TableName = "storage_migration_task")]
public class StorageMigrationTask
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
public StorageMigrationTaskStatus Status { get; set; }
[SugarColumn(IsNullable = true)]
public AppStorageType? TargetStorageType { get; set; }
public int Concurrency { get; set; } = 1;
public int TotalCount { get; set; }
public int PendingCount { get; set; }
public int SuccessCount { get; set; }
public int WarningCount { get; set; }
public int FailedCount { get; set; }
public int RemovedCount { get; set; }
public long TotalBytes { get; set; }
[SugarColumn(Length = 128)]
public string ConfigurationFingerprint { get; set; }
[SugarColumn(Length = 200, IsNullable = true)]
public string CurrentVideoId { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string CurrentFile { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
public DateTime CreatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? StartedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CompletedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CleanedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? RolledBackAt { get; set; }
/// <summary>
/// 已归档的终态任务不再出现在系统配置和任务中心,但保留条目用于审计及失败记录处理。
/// </summary>
public bool IsArchived { get; set; }
}
}
+42
View File
@@ -0,0 +1,42 @@
using dy.net.model.dto;
using SqlSugar;
using MediaStorageType = dy.net.model.dto.StorageType;
namespace dy.net.model.entity
{
[SugarTable(TableName = "video_download_task")]
[SugarIndex("idx_video_task_created", nameof(CreatedAt), OrderByType.Desc)]
public class VideoDownloadTask
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
public VideoTaskType Type { get; set; }
public VideoTaskTrigger Trigger { get; set; }
public VideoTaskStatus Status { get; set; }
[SugarColumn(IsNullable = true)]
public VideoTypeEnum? VideoType { get; set; }
public MediaStorageType StorageType { get; set; }
[SugarColumn(Length = 500)]
public string Title { get; set; }
[SugarColumn(Length = 128, IsNullable = true)]
public string StorageFingerprint { get; set; }
public int TotalCount { get; set; }
public int PendingCount { get; set; }
public int RunningCount { get; set; }
public int SuccessCount { get; set; }
public int WarningCount { get; set; }
public int FailedCount { get; set; }
public int SkippedCount { get; set; }
public bool IsArchived { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string CurrentFile { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
public DateTime CreatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? StartedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CompletedAt { get; set; }
}
}
+65
View File
@@ -0,0 +1,65 @@
using dy.net.model.dto;
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "video_download_task_item")]
[SugarIndex("idx_video_task_item_task_stage", nameof(TaskId), OrderByType.Asc, nameof(Stage), OrderByType.Asc)]
public class VideoDownloadTaskItem
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; }
[SugarColumn(Length = 50)]
public string TaskId { get; set; }
[SugarColumn(Length = 200, IsNullable = true)]
public string VideoId { get; set; }
[SugarColumn(Length = 200, IsNullable = true)]
public string AwemeId { get; set; }
[SugarColumn(Length = 200, IsNullable = true)]
public string CookieId { get; set; }
[SugarColumn(Length = 500, IsNullable = true)]
public string CookieName { get; set; }
[SugarColumn(IsNullable = true)]
public VideoTypeEnum? VideoType { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string VideoTitle { get; set; }
[SugarColumn(Length = 500, IsNullable = true)]
public string Author { get; set; }
[SugarColumn(Length = 2000, IsNullable = true)]
public string TargetPath { get; set; }
public VideoTaskItemStage Stage { get; set; }
public VideoTaskErrorType ErrorType { get; set; }
public VideoTaskSkipReason SkipReason { get; set; }
public int Attempts { get; set; }
public bool WorkerManaged { get; set; }
public long ExpectedLength { get; set; }
public long ActualLength { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string SourceUrlsJson { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string RetrySnapshotJson { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string ErrorMessage { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string WarningMessage { get; set; }
public bool CleanupPending { get; set; }
[SugarColumn(ColumnDataType = "TEXT", Length = -1, IsNullable = true)]
public string CleanupError { get; set; }
[SugarColumn(Length = 255, IsNullable = true)]
public string SourceHost { get; set; }
[SugarColumn(IsNullable = true)]
public int? HttpStatusCode { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? RetryAfter { get; set; }
[SugarColumn(Length = 50, IsNullable = true)]
public string ExclusionId { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? ExclusionReleasedAt { get; set; }
[SugarColumn(Length = 50, IsNullable = true)]
public string RelatedTaskId { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CompletedAt { get; set; }
}
}
+31
View File
@@ -0,0 +1,31 @@
using SqlSugar;
namespace dy.net.model.entity
{
[SugarTable(TableName = "dy_webdav_settings")]
public class WebDavSettings
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Id { get; set; } = "default";
[SugarColumn(Length = 1000, IsNullable = true)]
public string Endpoint { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string BasePath { get; set; } = "/dysync";
[SugarColumn(Length = 500, IsNullable = true)]
public string UserName { get; set; }
[SugarColumn(Length = -1, IsNullable = true)]
public string ProtectedPassword { get; set; }
public bool AllowInvalidCertificate { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastTestedAt { get; set; }
[SugarColumn(Length = 1000, IsNullable = true)]
public string LastTestMessage { get; set; }
}
}