# 主应用:文件页 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 被调用,未校验操作系统保存结果。