# Changelog — files.html + sync_v2.py 全面迭代 **日期**: 2026-05-30 **Commit**: 14131f9 **类型**: 安全加固 + 功能补全 + UX 全面改进 **涉及文件**: - `server/api/sync_v2.py` — 符号链接解析 + 新增 3 个端点 - `server/api/schemas.py` — 新增 FileDownload/FileRead/FileWrite schema - `web/app/files.html` — 前端全面重写 ## 后端变更 (sync_v2.py) ### P2-1/P3-2: 符号链接解析 - `ls -la` 解析逻辑新增 `is_link` 字段(检测 `l` 权限) - 符号链接文件名 `name -> target` 分离为 `name` + `link_target` - 响应新增 `is_link` 和 `link_target` 字段 ### P2-7: 新增 `/api/sync/download` 端点 - 通过 SFTP 流式下载远程文件 - 使用 `StreamingResponse` + 64KB chunk 避免内存膨胀 - 审计日志记录 ### P2-8: 新增 `/api/sync/read-file` + `/write-file` 端点 - `read-file`: `stat` 检查大小 → `cat` 读取内容,限制 1MB - `write-file`: base64 编码内容避免 shell 注入,`echo | base64 -d | tee` 写入 - 两个端点均有审计日志 ## 前端全面重写 (files.html) ### P1-1: 目录删除二次确认 - 目录删除:自定义模态框 + 要求输入目录名确认 - 文件删除:自定义确认模态框 ### P2-2/P2-3: 事件委托 - 移除所有内联 `onclick="..."` 字符串拼接 - 改用 `data-action` + `data-path` + `data-name` 属性 - 统一事件委托 `fileListEl.addEventListener('click', ...)` - 彻底消除 XSS 向量 ### P2-4: 上传进度条 - `XMLHttpRequest.upload.onprogress` 实时进度 - 顶部进度条显示当前文件名 + 百分比 + 进度条动画 ### P2-5: 文件大小可读化 - `formatSize()` 函数:字节 → B/KB/MB/GB - 保留 1 位小数 ### P2-6: 文件类型图标 - 30+ 文件扩展名映射 - `.py`→🐍 `.jpg`→🖼️ `.tar.gz`→📦 `.log`→📊 `.env`→🔒 等 ### P2-7: 文件下载 - 每行 hover 显示 ⬇ 下载按钮 - 点击触发 SFTP 下载 → 浏览器保存文件 ### P2-8: 文件预览/编辑 - 每行 hover 显示 👁 预览按钮 - 点击读取文件内容 → 模态框显示 + textarea 编辑 + 保存 ### P2-9: 自定义模态框 - 完全替代原生 `prompt()` / `confirm()` - Tailwind 样式:暗色主题 + backdrop blur + 圆角 - 支持:文本提示 / 输入框 / 多行编辑 / 危险操作红色样式 ### P2-10: 批量操作 - 每行开头 checkbox + 表头全选 - 选中时底部出现批量操作栏(计数 + 批量删除 + 取消) ### P3-1: 文件搜索 - 面包屑右侧搜索框 - 前端实时过滤文件名 ### P3-2: 符号链接显示 - 🔗 图标 + cyan 颜色 - hover 显示 `→ target` tooltip ### P3-3: 空目录状态 - 📂 大图标 + 提示文字 + 「上传文件」引导按钮 ### P3-4: 服务器刷新 - 🔄 按钮在服务器下拉旁,点击重新加载列表 ### P3-5: 操作 loading - 上传期间顶部进度条持续显示 - 浏览期间文件列表显示 ⏳ 加载动画 ## 验证结果 | 测试 | 结果 | |------|------| | 健康检查 | ✅ ok | | 页面加载 | ✅ 0 errors | | 浏览 /tmp | ✅ 文件列表+图标+大小正确 | | 符号链接 mysql.sock | ✅ 🔗 图标 | | 面包屑 | ✅ /tmp 路径 | | 搜索框 | ✅ 存在 | | 全选 checkbox | ✅ 存在 | | 操作按钮 | ✅ 👁 ⬏ ✏ 🗑 | ## 是否需迁移/重启 - 需要重启后端服务(新增 3 个 API 端点)