# Assets 模块业务逻辑

## 模块职责

Assets 模块负责首页中的相册、相册云盘、素材管理和样片管理入口。

- `album_list` 进入 `AlbumListView`。
- `album_trailer` 进入 `AlbumTrailerEntryView`。
- `cloud_management` 进入 `CloudStorageView`。
- `cloud_storage_transit` 进入 `CloudStorageTransitView`。
- `asset_management` 进入 `MediaLibraryView(kind: .material)`。
- `material_upload` 进入 `MediaLibraryUploadView`。
- `sample_management` 进入 `MediaLibraryView(kind: .sample)`。
- `sample_upload` 进入 `MediaLibraryUploadView(kind: .sample)`。

样片复用媒体库列表、详情、上下架、删除和 OSS 上传链路；上传样片额外要求选择关联项目。

## 相册管理逻辑

`AlbumListViewModel` 只保存相册列表、搜索条件、日期筛选、分页和创建状态。缺少当前景区时清空列表并停止请求接口。

相册列表流程：

1. 页面从 `AccountContext.currentScenic` 读取当前景区 ID。
2. 调用 `albumFolderList` 获取 `cloud_folder_type = 1` 的相册文件夹。
3. 支持按相册名称、开始时间、结束时间筛选。
4. 新建相册调用 `addAlbumFolder`，成功后刷新第一页。

`AlbumDetailViewModel` 管理单个相册的信息和文件列表。图片和视频通过 `AlbumFileTab` 区分，图片使用 `file_type = 2`，视频使用 `file_type = 1`。详情页支持编辑相册名称、编辑备注、设置封面和删除相册文件，操作成功后刷新详情。

相册文件预览使用 `RemoteImage` 展示图片，视频使用系统 `VideoPlayer` 播放。

## 相册预览上传逻辑

`AlbumTrailerViewModel` 管理相册选择、本地图片/视频选择、上传进度和提交状态。

上传流程：

1. 页面加载当前景区下的相册列表。
2. 用户通过 `PhotosPicker` 选择图片或视频。
3. 提交时先调用 `OSSUploadService.uploadAlbumFile` 上传到 OSS。
4. 上传成功后调用 `albumFileUploadURL` 把文件 URL 写入相册。
5. 任一文件上传失败时停止后续入库，并保留错误提示。

本地文件数据、OSS STS 和上传进度只保存在当前上传流程内，不落盘。

## 云盘逻辑

`CloudStorageViewModel` 只保存云盘模块内状态，包括目录路径、文件列表、筛选、排序、分页和当前操作状态。

云盘上传流程：

1. 页面通过 `PhotosPicker` 选择图片或视频。
2. `CloudStorageViewModel` 调用 `checkCloudUploadPermission`。
3. 权限通过后调用 `OSSUploadService.uploadCloudFile` 上传到 OSS。
4. 上传成功后调用 `cloudFileUpload` 把文件 URL 写入云盘。
5. 刷新当前目录列表。

下载文件只保存到 App 沙盒 `Documents/CloudDownloads`，不自动写入系统相册。上传/下载记录由 `CloudTransferStore` 保存，生命周期仅限本次 App 会话，不落盘。

## 素材/样片管理逻辑

`MediaLibraryViewModel` 按 `MediaLibraryKind` 管理素材或样片列表、关键词、审核状态、分页、详情、删除和上下架。素材接口使用 `type = 1`，样片接口使用 `type = 2`。

媒体库上下架规则：

- 审核通过的素材或样片可以上下架。
- 审核未通过或待审核的素材或样片禁止上下架。
- 操作成功后刷新当前媒体库列表。

`MediaLibraryEditorViewModel` 管理上传和编辑表单。提交前会校验名称、当前景区、打卡点、封面、媒体文件和标签长度。样片上传还会加载当前景区下的项目列表，并强制选择关联项目。

素材/样片上传流程：

1. 页面通过 `PhotosPicker` 选择封面和媒体文件。
2. 打卡点来源于 `ScenicSpotContext.spots`。
3. 样片上传从 `projectList` 获取可关联项目，提交时携带 `project_id`。
4. 提交时先把封面和媒体文件上传 OSS。
5. 再把最终 OSS URL、文件尺寸、文件大小、打卡点 ID、标签和项目 ID 提交给媒体库接口。
6. 上传失败时不提交媒体库接口。

## 缓存边界

相册列表、相册文件列表、云盘文件列表、素材列表、样片列表、项目选择、上传进度、下载记录、OSS STS、本地文件数据和媒体库表单都不进入 `AppSession`、`AccountContext` 或 TabBar 状态。

图片缓存继续交给 Kingfisher 的 `RemoteImage`。业务模块不自行缓存远程图片文件或 `Data`。

## 测试要求

新增相册、云盘、素材或样片逻辑时，需要同步补充 API、ViewModel 和路由测试。测试不通过时先修复问题，再继续迁移后续功能。
