# Story 13.16: FileSelector 添加 uploadOnly 模式

Status: done

<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->

## Story

作为 开发者，
我想要 给 FileSelector 组件添加 uploadOnly 属性，
以便 解决残疾人上传资料时的性能问题（弹窗加载慢因为需要一次性加载所有现有文件缩略图）。

## Acceptance Criteria

1. [AC: #1] FileSelector 组件新增 `uploadOnly` 可选属性（布尔类型，默认 false） ✅
2. [AC: #2] 当 `uploadOnly=true` 时：
   - 对话框只显示上传区域（MinioUploader） ✅
   - 不显示现有文件列表 ✅
   - 不调用文件列表查询 API ✅
3. [AC: #3] 上传成功后自动选中该文件并关闭对话框，直接返回 fileId ✅
4. [AC: #4] `uploadOnly` 模式与现有的 `allowMultiple` 模式兼容 ✅
5. [AC: #5] 保留现有功能：当 `uploadOnly=false` 或未设置时，行为与原来完全一致 ✅
6. [AC: #6] 更新 TypeScript 类型定义，确保类型安全 ✅
7. [AC: #7] 添加单元测试验证 uploadOnly 模式功能 ✅
8. [AC: #8] 更新组件 JSDoc 注释说明 uploadOnly 属性 ✅

## Tasks / Subtasks

- [x] Task 1: 更新 FileSelectorProps 接口和组件逻辑 (AC: #1, #2, #6)
  - [x] Subtask 1.1: 在 FileSelectorProps 接口中添加 `uploadOnly?: boolean` 属性
  - [x] Subtask 1.2: 修改对话框内容渲染逻辑，当 uploadOnly=true 时隐藏文件列表
  - [x] Subtask 1.3: 条件性地禁用文件列表查询（当 uploadOnly=true 时不执行 useQuery）
  - [x] Subtask 1.4: 修改 onUploadSuccess 回调逻辑，在 uploadOnly 模式下直接选中并关闭
- [x] Task 2: 更新 FileSelector 组件 UI 逻辑 (AC: #3, #4, #5)
  - [x] Subtask 2.1: 调整 uploadOnly 模式下的对话框布局（只显示 MinioUploader）
  - [x] Subtask 2.2: 确保与 allowMultiple 多选模式兼容
  - [x] Subtask 2.3: 验证默认行为（uploadOnly=false 或未设置）与原组件一致
- [x] Task 3: 添加单元测试 (AC: #7)
  - [x] Subtask 3.1: 创建测试用例验证 uploadOnly=true 时文件列表不加载
  - [x] Subtask 3.2: 创建测试用例验证上传成功后自动选中和关闭
  - [x] Subtask 3.3: 创建测试用例验证与 allowMultiple 的兼容性
- [x] Task 4: 更新文档和类型定义 (AC: #6, #8)
  - [x] Subtask 4.1: 更新 JSDoc 注释说明 uploadOnly 属性用途
  - [x] Subtask 4.2: 确认 TypeScript 类型正确导出

## Dev Notes

### 相关架构模式和约束

- **React 19 组件模式**: 使用 `@tanstack/react-query` 管理服务器状态
- **类型安全**: 使用 TypeScript 严格模式，禁止 `any` 类型
- **Props 设计**: 遵循可选 props 模式，保持向后兼容性
- **条件渲染**: 使用条件渲染而非动态 props 切换

### 源代码组件

- **主要文件**: `packages/file-management-ui/src/components/FileSelector.tsx`
- **相关组件**: `packages/file-management-ui/src/components/MinioUploader.tsx`
- **测试文件**: `packages/file-management-ui/tests/components/FileSelector.test.tsx`
- **API 客户端**: `packages/file-management-ui/src/api/fileClient.ts`

### 测试标准摘要

- 使用 Vitest 作为测试运行器
- 使用 Testing Library 进行组件测试
- 覆盖率目标：单元测试 ≥80%
- 关键元素添加 `data-testid` 用于测试选择

### 性能优化要点

当 `uploadOnly=true` 时：
- 不执行 `useQuery` 获取文件列表（避免加载大量缩略图）
- 不渲染现有文件列表网格
- 上传成功后直接调用 `onChange` 并关闭对话框
- 减少对话框打开时的延迟

### Project Structure Notes

- **包路径**: `packages/file-management-ui/`
- **组件导出**: 通过 `src/components/index.ts` 统一导出
- **对齐统一项目结构**: 遵循 kebab-case 文件命名、PascalCase 组件命名

### References

- [Source: _bmad-output/project-context.md#React 19 (Web UI)]
- [Source: _bmad-output/project-context.md#测试规则]
- [Source: packages/file-management-ui/src/components/FileSelector.tsx]
- [Source: packages/file-management-ui/src/components/MinioUploader.tsx]

## Dev Agent Record

### Agent Model Used

d8d-model (claude-opus-4-5-20251101)

### Debug Log References

### Completion Notes List

✅ **Story 13.16 实现完成**

**主要变更：**
1. 在 `FileSelectorProps` 接口中添加 `uploadOnly?: boolean` 属性，默认值为 `false`
2. 更新文件列表查询的 `enabled` 条件为 `isOpen && !uploadOnly`，在 uploadOnly 模式下禁用查询
3. 修改 `handleUploadSuccess` 回调，在 uploadOnly 模式下：
   - 上传成功后通过文件名和大小匹配获取 fileId
   - 自动调用 `onChange` 并关闭对话框
4. 更新对话框内容渲染逻辑：
   - uploadOnly 模式下只显示 MinioUploader，不显示文件列表
   - 隐藏确认/取消按钮（因为上传成功后自动关闭）
5. 同时更新了 `file-management-ui` 和 `file-management-ui-mt` 两个版本

**性能优化效果：**
- uploadOnly 模式下不执行文件列表查询 API，避免加载大量缩略图
- 减少对话框打开时的延迟，提升用户体验

**测试覆盖：**
- 添加 5 个新的单元测试用例验证 uploadOnly 模式功能
- 所有 11 个 FileSelector 测试通过

**向后兼容性：**
- 默认值为 `false`，不影响现有代码
- uploadOnly=false 或未设置时，行为与原组件完全一致

### File List

- `packages/file-management-ui/src/components/FileSelector.tsx` - 添加 uploadOnly 属性和相关逻辑
- `packages/file-management-ui-mt/src/components/FileSelector.tsx` - 同步更新 -mt 版本
- `packages/file-management-ui/tests/components/FileSelector.test.tsx` - 添加 uploadOnly 模式单元测试
- `_bmad-output/implementation-artifacts/13-16-fileselector-uploadonly-mode.md` - Story 文件
- `_bmad-output/implementation-artifacts/sprint-status.yaml` - Sprint 状态更新
