Files 模块提供租户范围的文件资产管理,支持上传、下载、软删除和分页。文件与 Tickets 和 Chat 模块作为附件提供者集成。
端点
| 端点 | 方法 | 描述 |
|---|---|---|
/api/files | POST | 上传文件(multipart 表单) |
/api/files/{id} | GET | 按 asset ID 下载文件 |
/api/files/{id} | DELETE | 软删除文件 |
/api/files | GET | 分页文件列表 |
FileAsset 实体
public class FileAssetEntity : TenantSoftDeleteEntityBase{ public string FileName { get; set; } public string ContentType { get; set; } public long FileSizeBytes { get; set; } public string StoragePath { get; set; } public string? Description { get; set; }}架构
FileEndpoints (Minimal API) │ ▼FileAssetService │ ├── IFileAssetRepository → SqlSugarFileAssetRepository ├── IFileStorage → LocalFileStorage └── IFileEventPublisher → CapFileEventPublisher上传流程
- 客户端发送
POST /api/files,附带 multipart 表单数据 FileAssetService通过IFileStorage.SaveAsync()读取流- 元数据通过 SqlSugar 持久化到
FileAssetEntity IFileEventPublisher发布 file.uploaded 集成事件- 返回文件资源 ID 和元数据
跨模块附件
文件作为其他模块的附件骨干:
| 模块 | 附件服务 | 用途 |
|---|---|---|
| Tickets | FileAssetTicketAttachmentAccessService | 将文件附加到工单 |
| Chat | FileAssetChatAttachmentAccessService | 将文件附加到聊天消息 |
两者都实现特定模块的访问模式:
public interface ITicketAttachmentAccessService{ Task<FileAssetEntity?> GetAttachmentAsync(Guid attachmentId, CancellationToken ct);}
public interface IChatAttachmentAccessService{ Task<FileAssetEntity?> GetAttachmentAsync(Guid attachmentId, CancellationToken ct);}存储配置
{ "Storage": { "BasePath": "./storage/files" }}文件存储在 {basePath}/{year}/{month}/{guid}.{extension}。
另见
- 存储构建块 — IFileStorage 抽象