# 浏览器书签导入功能需求文档

## 1. 功能概述

### 1.1 功能目标
新增独立的浏览器书签导入功能，允许用户从浏览器导出的 HTML 书签文件中，选择性导入书签到本应用中。

### 1.2 功能定位
- **独立性**：此功能与现有的 JSON 导入/导出功能完全独立，不合并到 `ImportExportDialog` 组件中
- **入口位置**：在应用主界面（如 `AppShell` 或 `HomeView`）新增独立的"导入浏览器书签"按钮
- **交互方式**：点击按钮 → 上传 HTML 文件 → 解析并展示书签列表 → 用户选择 → 导入选中项

## 2. 功能需求

### 2.1 入口设计

#### 2.1.1 按钮位置
- **主入口**：在 `AppShell.vue` 的 hero 区域，与"导入数据"按钮并列，或单独放置
- **按钮文案**：`导入浏览器书签` 或 `从浏览器导入`
- **按钮样式**：与现有按钮风格保持一致（Element Plus 按钮组件）

#### 2.1.2 触发方式
- 点击按钮打开独立的导入对话框
- 对话框标题：`导入浏览器书签`

### 2.2 文件上传

#### 2.2.1 上传方式
- 支持拖拽上传
- 支持点击选择文件
- 文件类型限制：`.html` 文件
- 文件大小限制：建议 10MB（可根据实际情况调整）

#### 2.2.2 文件格式支持
- **标准格式**：Netscape 书签格式（Chrome、Firefox、Edge 等主流浏览器导出格式）
- **文件结构**：
  ```html
  <!DOCTYPE NETSCAPE-Bookmark-file-1>
  <DT><A HREF="URL" ADD_DATE="时间戳" ICON="图标">标题</A>
  <DT><H3>文件夹名</H3>
  <DL><p>...</DL><p>
  ```

### 2.3 HTML 解析功能

#### 2.3.1 解析要求
- 使用浏览器原生 `DOMParser` API 解析 HTML
- 递归遍历 `<DL>` 结构，提取所有书签项
- 提取字段：
  - `HREF` → `url`（必需）
  - 文本内容 → `title`（必需）
  - `ADD_DATE` → `createdAt`（可选，Unix 时间戳转 Date）
  - `ICON` → `icon`（可选，base64 或 URL）
  - 文件夹路径 → `tags` 或 `folderPath`（可选，用于展示来源）

#### 2.3.2 数据验证
- 过滤无效书签：缺少 `url` 或 `title` 的书签项
- 处理编码问题：支持 UTF-8 编码
- 错误处理：文件格式错误时给出明确提示

### 2.4 书签列表展示

#### 2.4.1 列表组件
- 使用 Element Plus 的 `el-table` 组件
- 表格列：
  - **复选框列**：支持单选和全选
  - **标题列**：显示书签标题（可点击预览 URL）
  - **URL 列**：显示完整 URL（可截断显示，hover 显示完整）
  - **来源文件夹列**：显示书签所在的文件夹路径（可选）
  - **添加时间列**：显示原始添加时间（从 ADD_DATE 转换）
  - **tab列**：可以在表格中给这个书签添加标签
  --**备注列**：可以添加备注

#### 2.4.2 交互功能
- **全选/取消全选**：表头复选框控制所有项
- **单选**：每行复选框控制单个项
- **搜索/筛选**：
  - 顶部搜索框，支持按标题、URL 搜索
  - 支持按文件夹筛选（如果保留文件夹信息）
- **分页**：如果书签数量 > 100，使用分页显示（每页 50 条）
- **统计信息**：
  - 显示总书签数
  - 显示已选择数量
  - 显示可导入数量（排除无效项）

#### 2.4.3 状态显示
- **加载状态**：解析文件时显示加载动画
- **空状态**：无有效书签时显示提示
- **错误状态**：解析失败时显示错误信息

### 2.5 选择性导入

#### 2.5.1 导入流程
1. 用户勾选需要导入的书签
2. 点击"导入选中项"按钮
3. 显示确认对话框：`确定要导入 X 条书签吗？`
4. 执行导入操作
5. 显示导入结果反馈

#### 2.5.2 数据转换规则
```javascript
// 浏览器书签格式 → 应用数据格式
{
  id: uuidv4(),                    // 生成新 ID
  title: "书签标题",                // 必需
  url: "https://...",              // 必需
  icon: "data:image/png;base64,..." // 可选，从 ICON 属性提取
  description: "",                 // 默认空
  tags: [],               // 可为空，表格中输入的
  projectIds: [],                  // 默认空数组
  visitCount: 0,                   // 默认 0
  lastVisitTime: null,             // 默认 null
  createdAt: new Date(ADD_DATE * 1000), // Unix 时间戳转 Date
  updatedAt: new Date(ADD_DATE * 1000)  // 同 createdAt
}
```

#### 2.5.3 重复处理
- **检测重复**：根据 URL 判断是否已存在
- **处理方式**：
  - 方案 A：跳过重复项，导入时提示"X 条书签已存在，已跳过"

#### 2.5.4 导入结果反馈
- 成功：`已成功导入 X 条书签`
- 部分成功：`已导入 X 条书签，Y 条已存在已跳过，Z 条无效已忽略`
- 失败：显示具体错误信息

## 3. 技术实现方案

### 3.1 文件结构

```
src/
├── components/
│   └── links/
│       ├── ImportExportDialog.vue          # 现有组件，不修改
│       └── BrowserBookmarkImportDialog.vue # 新增：浏览器书签导入对话框
├── utils/
│   └── bookmarkParser.js                   # 新增：HTML 解析工具函数
└── stores/
    └── links.js                            # 扩展：添加处理浏览器书签的方法
```

### 3.2 核心组件设计

#### 3.2.1 BrowserBookmarkImportDialog.vue
**职责**：
- 文件上传界面
- 调用解析工具解析 HTML
- 展示书签列表（使用 el-table）
- 处理用户选择
- 调用 store 方法导入数据

**Props**：
- `modelValue: Boolean` - 控制对话框显示/隐藏

**Events**：
- `update:modelValue` - 更新显示状态

**状态管理**：
- `isParsing: Boolean` - 解析中状态
- `parsedBookmarks: Array` - 解析后的书签列表
- `selectedBookmarks: Array` - 用户选中的书签 ID 列表
- `searchKeyword: String` - 搜索关键词
- `isImporting: Boolean` - 导入中状态

#### 3.2.2 bookmarkParser.js
**功能**：
- `parseBookmarkHTML(htmlText: string): Array<BookmarkItem>`
  - 输入：HTML 文本内容
  - 输出：解析后的书签对象数组
  - 处理：递归解析 DOM 结构，提取书签信息

**数据结构**：
```javascript
interface BookmarkItem {
  title: string        // 书签标题
  url: string          // 书签 URL
  icon?: string        // 图标（base64 或 URL）
  addDate?: number     // Unix 时间戳（秒）
  folderPath?: string  // 文件夹路径（如 "收藏夹栏/工作"）
}
```

### 3.3 Store 扩展

#### 3.3.1 links.js 扩展方法
```javascript
// 新增方法：处理浏览器书签格式的导入
async function importBrowserBookmarks(bookmarkItems, options = {}) {
  // 1. 转换数据格式
  // 2. 检测重复
  // 3. 调用现有的 importLinks 方法
  // 4. 返回导入结果统计
}
```

### 3.4 UI 交互流程

```
用户点击"导入浏览器书签"按钮
    ↓
打开 BrowserBookmarkImportDialog
    ↓
用户上传 HTML 文件
    ↓
显示解析中状态
    ↓
解析完成，展示书签列表
    ↓
用户勾选需要导入的书签
    ↓
点击"导入选中项"
    ↓
显示确认对话框
    ↓
执行导入
    ↓
显示导入结果
    ↓
关闭对话框，刷新书签列表
```

## 4. UI/UX 设计

### 4.1 对话框布局

```
┌─────────────────────────────────────────┐
│  导入浏览器书签                    [×]   │
├─────────────────────────────────────────┤
│                                         │
│  [文件上传区域]                         │
│  拖拽 HTML 文件到此处或点击上传          │
│                                         │
├─────────────────────────────────────────┤
│  [搜索框] 总书签数: X  已选择: Y        │
├─────────────────────────────────────────┤
│  ☑ [全选]  标题  │  URL  │  来源  │ 时间│
│  ☐ 书签1   │ ... │ ... │ ... │ ... │
│  ☐ 书签2   │ ... │ ... │ ... │ ... │
│  ...                                    │
│                                         │
│  [分页组件]                              │
├─────────────────────────────────────────┤
│              [取消]  [导入选中项]        │
└─────────────────────────────────────────┘
```

### 4.2 按钮样式
- **导入浏览器书签按钮**：与"导入数据"按钮样式一致，使用 `el-button` 的 `text` 或 `default` 类型
- **导入选中项按钮**：使用 `primary` 类型，突出主要操作

### 4.3 响应式设计
- 对话框宽度：桌面端 `800px`，移动端 `90vw`
- 表格列：移动端可考虑隐藏部分列或使用卡片布局

## 5. 边界情况处理

### 5.1 文件相关
- **文件格式错误**：提示"文件格式不正确，请上传浏览器导出的 HTML 书签文件"
- **文件过大**：提示"文件过大，请选择较小的文件"（建议限制 10MB）
- **空文件**：提示"文件中没有找到书签数据"

### 5.2 解析相关
- **解析失败**：捕获异常，显示友好错误提示
- **无效书签**：自动过滤，在统计中显示"X 条无效书签已忽略"
- **编码问题**：尝试多种编码方式解析

### 5.3 数据相关
- **大量书签**：使用分页或虚拟滚动，避免性能问题
- **重复书签**：自动检测并跳过，在结果中提示
- **特殊字符**：正确处理 URL 编码和 HTML 实体

### 5.4 用户体验
- **加载反馈**：解析和导入时显示加载状态
- **操作确认**：导入前显示确认对话框
- **结果反馈**：导入完成后显示详细结果统计

## 6. 测试要点

### 6.1 功能测试
- [ ] 上传标准 Chrome 书签文件
- [ ] 上传标准 Firefox 书签文件
- [ ] 上传标准 Edge 书签文件
- [ ] 解析包含文件夹的书签文件
- [ ] 解析包含大量书签的文件（> 1000 条）
- [ ] 选择性导入功能
- [ ] 重复书签检测
- [ ] 无效书签过滤

### 6.2 边界测试
- [ ] 上传非 HTML 文件
- [ ] 上传损坏的 HTML 文件
- [ ] 上传空文件
- [ ] 上传超大文件（> 10MB）
- [ ] 导入 0 条书签
- [ ] 导入全部重复的书签

### 6.3 用户体验测试
- [ ] 加载状态显示
- [ ] 错误提示友好性
- [ ] 操作流程顺畅性
- [ ] 响应式布局适配

## 7. 开发优先级

### Phase 1: 核心功能（MVP）
1. 创建 `BrowserBookmarkImportDialog.vue` 组件
2. 实现 HTML 解析工具函数
3. 实现文件上传和解析
4. 实现基础的书签列表展示
5. 实现选择性导入功能

### Phase 2: 增强功能
1. 添加搜索/筛选功能
2. 添加分页功能
3. 优化大量数据的性能
4. 添加文件夹路径展示

### Phase 3: 优化体验
1. 优化错误提示
2. 添加导入进度显示
3. 优化响应式布局
4. 添加导入历史记录（可选）

## 8. 注意事项

1. **独立性**：此功能完全独立，不影响现有的 JSON 导入/导出功能
2. **向后兼容**：新增功能不应破坏现有功能
3. **性能考虑**：处理大量书签时注意性能优化
4. **错误处理**：所有可能的错误情况都要有友好的提示
5. **代码复用**：尽量复用现有的工具函数和组件样式

## 9. 后续扩展（可选）

- 支持导入时自动创建文件夹结构
- 支持批量编辑导入的书签
- 支持导入预览（导入前预览效果）
- 支持导入历史记录
- 支持从多个浏览器书签文件合并导入

