# 主应用：文件页 UI/UX

## 1. 页面定义

| 项目 | 内容 |
| --- | --- |
| 页面名称 | 文件管理 |
| 路由 | `/files` |
| 页面实现 | `app-instance/frontend/app/(app)/files/page.tsx` |
| 关键组件 | `FilesPage`、`FilePreviewPanel`、`FileIcon`、`ScrollArea` |
| 核心任务 | 浏览目录、创建文件夹、上传文件、预览文本/Markdown/图片/二进制文件、下载文件、删除文件或目录 |
| 测试状态 | 已修复并复测通过；本地与 `terminaltest` 生产实例均通过 |

## 2. 信息架构与组件层级

```text
AppShell
└── main.pt-16
    └── /files
        ├── Page Header
        │   ├── h1 Files
        │   ├── New folder
        │   ├── Upload
        │   ├── hidden file input
        │   └── Refresh
        ├── Breadcrumbs
        │   ├── Files root
        │   └── 当前路径 segments
        ├── New directory form
        │   ├── Folder name input
        │   ├── Create
        │   └── Cancel
        └── Content grid
            ├── File list panel
            │   ├── Loading state
            │   ├── Error state + Retry
            │   ├── Empty state
            │   └── File / Directory rows
            │       ├── Open / Preview primary button
            │       ├── Download
            │       └── Delete
            └── FilePreviewPanel
                ├── Empty preview
                ├── Loading preview
                ├── Error preview
                ├── File metadata
                ├── Download
                ├── Image preview
                ├── Markdown preview
                ├── Text preview
                └── Binary fallback
```

## 3. 布局与响应式规则

- 页面外层使用 `max-w-7xl`，移动端内边距为 `16px`，桌面端为 `24px`。
- 内容区默认单列，`lg` 以上改为左侧文件列表、右侧预览双栏。
- 左侧文件列表和右侧预览都使用 `min-w-0`，避免长文件名、Markdown、代码块撑破页面。
- 文件行移动端为上下结构：上方文件信息，下方下载/删除操作；`sm` 以上恢复横向布局。
- 下载/删除在移动端始终可见，桌面端保留 hover 显示。
- 根目录也允许创建文件夹和上传文件；空态文案与按钮行为一致。
- 面包屑、文件行主按钮、下载、删除、创建、取消、刷新等主要可点击目标均为 `44px` 以上。

## 4. 操作与 UX 逻辑

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 刷新文件列表 | 点击 Refresh | 调用 browse 接口重新加载当前路径 | 获取最新目录状态 | 正常 |
| 根目录新建文件夹 | 点击 New folder，输入名称，点击 Create | 调用 mkdir，成功后刷新列表 | 空 workspace 也能开始组织文件 | 正常 |
| 根目录上传文件 | 点击 Upload，选择文件 | 调用 upload，显示进度并刷新列表 | 空 workspace 也能添加文件 | 正常 |
| 进入目录 | 点击目录主区域 | 调用 browse，更新 breadcrumbs 和列表 | 浏览层级文件 | 正常 |
| 返回上级或根目录 | 点击 breadcrumbs | 调用 browse 对应路径 | 快速导航 | 正常 |
| 预览文件 | 点击文件主区域 | 调用 preview，右侧显示内容 | 快速查看文件 | 正常 |
| 下载文件 | 点击文件行或预览区 Download | 调用 download，浏览器下载 blob | 获取原始文件 | 正常 |
| 删除文件/目录 | 点击 Delete 并确认 | 调用 delete，成功后从列表移除 | 管理文件空间，防误删 | 正常 |
| 加载失败 | browse 接口失败 | 显示错误、详情和 Retry | 明确异常恢复路径 | 正常 |
| 二进制文件预览 | 文件不可预览 | 显示不可直接预览提示 | 避免乱码 | 正常 |

## 5. 响应式测试矩阵

测试日期：2026-06-04。浏览器：Playwright Chromium。环境：本地 dev server `http://127.0.0.1:3080` 与生产实例 `terminaltest`；API 使用模拟数据，真实浏览器执行点击、上传入口、目录切换、预览、下载、删除确认和截图。

| 页面/状态 | 视口 | 横向越界 | 小触控目标 | 关键结论 |
| --- | --- | --- | --- | --- |
| 根目录空态 | `390×844` | 无 | 0 | New folder 和 Upload 在根目录可用 |
| 文件预览 | `390×844` | 无 | 0 | 可进入目录、预览 Markdown、下载、删除 |
| 加载错误 | `390×844` | 无 | 0 | 错误和 Retry 可见 |
| 文件预览 | `320×568` | 无 | 0 | 长文件名、操作按钮、Markdown 预览均未撑破页面 |
| 文件预览 | `390×844` | 无 | 0 | 手机竖屏布局清晰 |
| 文件预览 | `844×390` 横屏 | 无 | 0 | 横屏无页面级横向滚动 |
| 文件预览 | `768×1024` | 无 | 0 | 平板布局稳定 |
| 文件预览 | `1365×900` | 无 | 0 | 桌面双栏布局正常 |

### 关键量化证据

- 本地文件页 QA 自动化用例 `4 passed`。
- 部署到 `terminaltest` 后，同一套文件页 QA 自动化用例 `4 passed`。
- 根目录空态中 `New folder` 和 `Upload` 均为 enabled。
- 创建文件夹调用 `/api/user-files/mkdir?path=docs`。
- 下载调用 `/api/user-files/download`。
- 删除调用 `/api/user-files/delete`，并经过浏览器确认。
- 实测 `320×568`、`390×844`、`844×390`、`768×1024`、`1365×900` 均无页面级横向越界。
- 所有实测视口可见小触控目标数为 `0`。

## 6. 已修复问题

| 等级 | 问题 | 修复 |
| --- | --- | --- |
| P1 | 根目录空态提示可上传/新建，但按钮被禁用 | 根目录允许 New folder 和 Upload |
| P1 | `320px` 下文件列表被 `minmax(360px,440px)` 和长文件名撑破页面 | 默认单列改为 `minmax(0,1fr)`，列表和预览加 `min-w-0` |
| P1 | 文件行里嵌套下载/删除 role button，移动端不可发现且触控小 | 改为主打开按钮 + 独立下载/删除按钮，移动端始终可见 |
| P2 | 文件行长文件名与操作按钮互相挤压 | 移动端文件行改为信息在上、操作在下 |
| P2 | Refresh 是 icon-only 且缺少可访问名称 | 补充 `aria-label/title`，命中区为 `44px` |
| P2 | 面包屑按钮和文件主按钮触控高度不足 | 固定为 `44px` 以上 |
| P2 | Markdown/text 预览长内容可能撑破页面 | 预览区增加容器内换行和 preserved long text 规则 |

## 7. 剩余观察项

- 本轮自动化使用模拟 API 数据覆盖常见文件类型；真实大文件、超大图片、深层目录和上传失败恢复仍需持续观察。
- 浏览器原生下载行为只验证 download API 被调用，未校验操作系统保存结果。
