This commit is contained in:
2026-03-29 23:17:20 +08:00
commit 7dc5e73af7
36 changed files with 1480 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
using OrpaonVision.ConfigApp.Annotation.Options;
using OrpaonVision.Core.Annotation;
using OrpaonVision.Core.Annotation.Contracts;
using OrpaonVision.Core.Enums;
using OrpaonVision.Core.Results;
namespace OrpaonVision.ConfigApp.Annotation.Services;
/// <summary>
/// CVAT 标注同步应用服务(骨架实现)。
///
/// 说明:
/// - 当前阶段先提供参数校验与返回契约,便于前后链路先跑通;
/// - 实际 HTTP 调用、认证、重试策略将在后续迭代补齐。
/// </summary>
public sealed class CvatAnnotationSyncAppService : IAnnotationSyncAppService
{
private readonly CvatOptions _options;
/// <summary>
/// 构造函数。
/// </summary>
/// <param name="options">CVAT 配置。</param>
public CvatAnnotationSyncAppService(CvatOptions options)
{
_options = options;
}
/// <inheritdoc />
public Task<Result> SyncProjectAsync(SyncAnnotationProjectCommand command, CancellationToken cancellationToken = default)
{
if (command.Platform != AnnotationPlatformEnum.Cvat)
{
return Task.FromResult(Result.Fail("ANNOTATION_PLATFORM_NOT_SUPPORTED", "当前版本仅支持 CVAT 平台同步。"));
}
if (command.ProjectId == Guid.Empty || command.AnnotationTaskId == Guid.Empty)
{
return Task.FromResult(Result.Fail("ANNOTATION_ARGUMENT_INVALID", "项目标识或标注任务标识无效。"));
}
if (string.IsNullOrWhiteSpace(command.CvatServerEndpoint))
{
return Task.FromResult(Result.Fail("ANNOTATION_ENDPOINT_REQUIRED", "CVAT 服务地址不能为空。"));
}
if (!Uri.TryCreate(command.CvatServerEndpoint, UriKind.Absolute, out _))
{
return Task.FromResult(Result.Fail("ANNOTATION_ENDPOINT_INVALID", "CVAT 服务地址格式不合法。"));
}
if (command.CvatTaskId <= 0 || command.CvatProjectId <= 0)
{
return Task.FromResult(Result.Fail("ANNOTATION_CVAT_ID_INVALID", "CVAT 项目 ID 或任务 ID 必须大于 0。"));
}
// 当前为骨架实现:预留后续与 CVAT API 的双向同步逻辑。
return Task.FromResult(Result.Success(message: "CVAT 同步请求已受理。"));
}
/// <inheritdoc />
public Task<Result<AnnotationSyncStatusDto>> GetSyncStatusAsync(Guid projectId, CancellationToken cancellationToken = default)
{
if (projectId == Guid.Empty)
{
return Task.FromResult(Result<AnnotationSyncStatusDto>.Fail("ANNOTATION_PROJECT_ID_INVALID", "项目标识不能为空。"));
}
var status = new AnnotationSyncStatusDto
{
ProjectId = projectId,
AnnotationTaskId = Guid.Empty,
Platform = AnnotationPlatformEnum.Cvat,
SyncStatus = AnnotationSyncStatusEnum.None,
ProgressPercent = 0,
LastSyncedAtUtc = null,
LastErrorMessage = null
};
return Task.FromResult(Result<AnnotationSyncStatusDto>.Success(status, message: $"CVAT 状态查询完成({_options.ServerEndpoint})。"));
}
}