using Microsoft.AspNetCore.Http; using MilliSim.Common.Dtos; using MilliSim.Common.Models; namespace MilliSim.Services; public interface IProjectService { // ===== 项目 ===== Task>> GetProjectsAsync(ProjectQueryRequest request); Task>> GetPublishedProjectsAsync(ProjectQueryRequest request); Task> GetProjectByIdAsync(long id, bool incrementView = false); Task> CreateProjectAsync(CreateProjectRequest request); Task> UpdateProjectAsync(long id, UpdateProjectRequest request); Task DeleteProjectAsync(long id); Task TogglePublishAsync(long id); Task ToggleFeaturedAsync(long id); Task ToggleFavoriteAsync(long projectId); Task>> GetFavoritesAsync(PageRequest request); Task RecordExperienceAsync(long projectId, int durationSeconds); Task>> GetExperienceLogsAsync(PageRequest request); Task>> GetRelatedProjectsAsync(long projectId, int count = 4); // ===== 项目分类 ===== Task>> GetCategoriesAsync(); Task> CreateCategoryAsync(CreateCategoryRequest request); Task> UpdateCategoryAsync(long id, CreateCategoryRequest request); Task DeleteCategoryAsync(long id); // ===== 平台类型 ===== Task>> GetPlatformsAsync(); Task> CreatePlatformAsync(CreatePlatformRequest request); Task> UpdatePlatformAsync(long id, CreatePlatformRequest request); Task DeletePlatformAsync(long id); // ===== 特性标签 ===== Task>> GetTagsAsync(); Task> CreateTagAsync(CreateTagRequest request); Task> UpdateTagAsync(long id, CreateTagRequest request); Task DeleteTagAsync(long id); // ===== 资源包 ===== Task>> GetPackagesAsync(long projectId); Task> UploadPackageAsync(long projectId, PackageType type, IFormFile file, string wakeProtocolPrefix, string wakeProtocolParam); Task DeletePackageAsync(long id); /// /// 下载资源包(返回文件流和原始文件名,用于 Content-Disposition) /// Task<(Stream Stream, string ContentType, string FileName)> DownloadPackageAsync(long packageId); /// /// 获取 WebGL 资源包的在线运行入口 URL(解压后的 index.html 签名 URL) /// Task> GetWebGLRunUrlAsync(long projectId); /// /// 获取 WebGL 代理后的 index.html 内容(注入 base 标签,资源走代理重定向到签名URL) /// Task GetWebGLIndexHtmlAsync(long projectId); /// /// 获取 WebGL 资源文件的签名 URL(用于资源代理重定向) /// Task GetWebGLResourceUrlAsync(long projectId, string resourcePath); /// /// 获取视频流(防盗链代理,不暴露 COS 直链,支持 Range 请求) /// Task<(Stream Stream, string ContentType, long? FileSize, bool IsPartial, string? ContentRange)> GetVideoStreamAsync(long projectId, string? rangeHeader); }