# 书签管理系统 - 数据库重构完整计划

## 一、重构背景

### 1.1 现有问题

原系统采用简化的数据表设计（4 张表：users, devices, bookmarks, refresh_tokens），存在以下问题：

| 问题 | 现状 | 影响 |
|------|------|------|
| **标签存储** | 书签表中的 `Tags` 字段使用 JSON 数组存储 | 无法高效查询、无法统计标签使用量、无法为标签设置颜色/图标 |
| **设备权限** | 书签表中的 `AllowedDevices` 字段使用 JSON 数组存储 | 无法建立外键约束、删除设备后残留无效数据 |
| **组织结构** | 书签只能通过标签分类，无层级结构 | 不支持文件夹嵌套、无法按目录组织书签 |
| **功能缺失** | 无收藏集合、分享、访问历史功能 | 用户体验受限 |

### 1.2 重构目标

将现有的 **4 张表**扩展为 **12 张表**，实现：

- **标签管理**：独立 Tag 表 + 关联表，支持标签元数据（颜色、图标、排序）
- **层级结构**：新增文件夹表，支持多级嵌套
- **设备权限**：改用关联表，支持外键约束和级联删除
- **新增功能**：收藏集合、分享链接、访问历史记录

### 1.3 表结构变化概览

| 类别 | 改造前 | 改造后 |
|------|--------|--------|
| 核心表 | users, devices, refresh_tokens | 保持不变 |
| 书签表 | bookmarks (含 JSON 字段) | bookmarks (精简) |
| 标签 | - | tags, bookmark_tags |
| 文件夹 | - | folders |
| 设备权限 | - | bookmark_device_permissions |
| 收藏集合 | - | collections, collection_bookmarks |
| 分享功能 | - | bookmark_shares |
| 访问历史 | - | bookmark_visits |

---

## 二、后端重构（已完成）

### 2.1 实体类变更

#### 修改的实体

| 文件 | 变更内容 |
|------|----------|
| `Bookmark.cs` | 移除 `Tags`(string[])、`AllowedDevices`(Guid[])；新增 `FolderId`；`Order` 从 long 改为 int；`LastVisitTime` 改名为 `LastVisitAt`；新增导航属性 |

#### 新增的实体

| 文件 | 说明 |
|------|------|
| `Folder.cs` | 文件夹实体，支持 ParentId 自引用实现多级嵌套 |
| `Tag.cs` | 标签实体，包含 Color、Icon、Order 字段 |
| `BookmarkTag.cs` | 书签-标签多对多关联表 |
| `BookmarkDevicePermission.cs` | 书签-设备权限关联表 |
| `Collection.cs` | 收藏集合实体 |
| `CollectionBookmark.cs` | 集合-书签多对多关联表 |
| `BookmarkShare.cs` | 分享链接实体，支持密码保护、过期时间、查看次数限制 |
| `BookmarkVisit.cs` | 访问历史实体 |

#### 新增的枚举

| 文件 | 说明 |
|------|------|
| `ShareType.cs` | 分享类型：Bookmark(1)/Folder(2)/Collection(3) |

### 2.2 DTO 变更

| DTO | 变更内容 |
|-----|----------|
| `BookmarkDto` | 新增 `FolderId`；`Tags` 从 `string[]` 改为 `List<TagDto>`；`LastVisitTime` 改名为 `LastVisitAt`；`Order` 从 long 改为 int |
| `TagDto` | 新增 `Id`、`Color`、`Icon`、`Order` 字段 |
| `CreateBookmarkRequest` | 新增 `FolderId` 字段 |
| `UpdateBookmarkRequest` | 新增 `FolderId`、`UpdateFolder` 字段 |

### 2.3 服务层重构

| 服务 | 变更内容 |
|------|----------|
| `BookmarkService` | 完全重写，使用 `IncludeMany` 加载 BookmarkTags 和 DevicePermissions；新增 `SyncBookmarkTagsAsync`、`SyncDevicePermissionsAsync` 私有方法 |
| `TagService` | 完全重写，使用独立 Tag 表；新增 `CreateTagAsync`、`UpdateTagAsync`、`GetTagAsync` 方法 |

### 2.4 接口变更

| 接口 | 变更内容 |
|------|----------|
| `ITagService` | 新增 `CreateTagAsync`、`UpdateTagAsync`、`GetTagAsync` 方法签名 |
| `IBookmarkService` | `GetUserBookmarksAsync` 新增 `folderId` 参数 |

### 2.5 控制器变更

| 控制器 | 变更内容 |
|--------|----------|
| `TagsController` | 新增完整的 CRUD 操作（创建、更新、删除标签） |
| `BookmarksController` | `GetBookmarks` 新增 `folderId` 查询参数 |
| `AdminController` | 修复 GetUserBookmarks 方法，使用新的实体结构 |

### 2.6 数据库初始化

`FreeSqlSetup.cs` 已更新：
- 注册所有 12 个实体类型
- 启动时自动同步表结构
- 提供 `SyncAllTables()` 方法手动同步
- 提供 `CheckDatabaseStatusAsync()` 方法检查数据库状态

---

## 三、前端重构计划

### 3.1 需要修改的文件清单

#### 3.1.1 类型定义 (`src/frontend/src/types/index.ts`)

| 修改项 | 当前 | 修改后 |
|--------|------|--------|
| `Bookmark.tags` | `string[]` | `Tag[]` |
| `Bookmark.lastVisitTime` | `lastVisitTime` | `lastVisitAt` |
| 新增 `Bookmark.folderId` | - | `folderId?: string` |
| `Tag` 接口 | `{ name: string; count: number }` | `{ id: string; name: string; color?: string; icon?: string; order: number; count: number }` |
| 新增 | - | `Folder` 接口 |
| 新增 | - | `Collection` 接口 |

```typescript
// 修改后的 Tag 接口
interface Tag {
  id: string;
  name: string;
  color?: string;
  icon?: string;
  order: number;
  count: number;
}

// 修改后的 Bookmark 接口
interface Bookmark {
  id: string;
  folderId?: string;  // 新增
  title: string;
  url: string;
  description?: string;
  icon?: string;
  tags: Tag[];  // 从 string[] 改为 Tag[]
  visitCount: number;
  lastVisitAt?: string;  // 重命名
  order: number;
  visibility: VisibilityType;
  allowedDevices?: string[];
  createdAt: string;
  updatedAt: string;
}

// 新增 Folder 接口
interface Folder {
  id: string;
  parentId?: string;
  name: string;
  icon?: string;
  order: number;
  children?: Folder[];
  bookmarks?: Bookmark[];
}
```

#### 3.1.2 API 层修改

**`src/frontend/src/api/bookmark.ts`**

| 方法 | 修改内容 |
|------|----------|
| `getBookmarks()` | 新增 `folderId` 参数：`getBookmarks(tag?: string, folderId?: string)` |
| 新增 | `getFolders()` - 获取文件夹列表 |
| 新增 | `createFolder()` - 创建文件夹 |
| 新增 | `updateFolder()` - 更新文件夹 |
| 新增 | `deleteFolder()` - 删除文件夹 |
| 新增 | `moveBookmark()` - 移动书签到文件夹 |

**`src/frontend/src/api/tag.ts`**

| 方法 | 修改内容 |
|------|----------|
| 新增 | `createTag(name, color?, icon?)` - 创建标签 |
| 新增 | `updateTag(id, name?, color?, icon?)` - 更新标签 |
| 修改 | `deleteTag(id)` - 参数从标签名改为标签ID |
| 修改 | `mergeTags(sourceTagIds, targetTagId)` - 参数从标签名改为标签ID |

#### 3.1.3 Store 层修改

**`src/frontend/src/stores/bookmark.ts`**

| 修改项 | 说明 |
|--------|------|
| 新增状态 | `currentFolderId: string \| null` - 当前文件夹 |
| 新增状态 | `folders: Folder[]` - 文件夹列表 |
| 修改 `fetchBookmarks` | 支持 `folderId` 参数 |
| 新增方法 | `fetchFolders()` - 获取文件夹列表 |
| 新增方法 | `createFolder()` - 创建文件夹 |
| 新增方法 | `deleteFolder()` - 删除文件夹 |
| 新增方法 | `setCurrentFolder()` - 切换文件夹 |
| 修改计算属性 | 适配新的 Tag 对象结构 |

**`src/frontend/src/stores/tag.ts`**

| 修改项 | 说明 |
|--------|------|
| 新增方法 | `createTag(name, color?, icon?)` |
| 新增方法 | `updateTag(id, name?, color?, icon?)` |
| 修改方法 | `deleteTag` 和 `mergeTags` 使用 ID 而非名称 |

#### 3.1.4 组件修改

**`src/frontend/src/components/bookmark/BookmarkList.vue`**

| 修改项 | 说明 |
|--------|------|
| 标签显示 | 从显示字符串改为显示带颜色的标签组件 |
| 新增 | 面包屑导航（显示当前文件夹路径） |

**`src/frontend/src/components/bookmark/BookmarkEditor.vue`**

| 修改项 | 说明 |
|--------|------|
| 标签选择 | 从字符串输入改为标签选择器（支持颜色预览） |
| 新增 | 文件夹选择器（树形结构） |
| 标签管理 | 支持创建带颜色的新标签 |

**新增组件**

| 组件 | 说明 |
|------|------|
| `FolderTree.vue` | 文件夹树形组件，支持展开/折叠、拖拽移动 |
| `TagBadge.vue` | 带颜色的标签徽章组件 |
| `TagManager.vue` | 标签管理弹窗（编辑颜色、图标、排序） |

#### 3.1.5 视图页面修改

**`src/frontend/src/views/HomeView.vue`**

| 修改项 | 说明 |
|--------|------|
| 左侧边栏 | 新增文件夹树导航 |
| 标签列表 | 显示标签颜色 |
| 面包屑 | 显示当前文件夹路径 |

### 3.2 前端修改优先级

| 优先级 | 任务 | 影响范围 |
|--------|------|----------|
| P0 | 修改类型定义 (types/index.ts) | 全局 |
| P0 | 修改 API 层适配新接口 | 全局 |
| P0 | 修改 Store 层适配新数据结构 | 全局 |
| P1 | 修改 BookmarkList 组件显示标签 | 书签列表 |
| P1 | 修改 BookmarkEditor 组件标签选择 | 书签编辑 |
| P2 | 新增文件夹相关组件和功能 | 新功能 |
| P2 | 新增标签管理功能 | 新功能 |

---

## 四、浏览器插件重构计划

### 4.1 需要修改的文件清单

#### 4.1.1 API 层 (`src/extension/shared/api.js`)

| 方法 | 修改内容 |
|------|----------|
| `getBookmarks(tag)` | 新增 `folderId` 参数：`getBookmarks(tag, folderId)` |
| `createBookmark(data)` | 请求体新增 `folderId` 字段 |
| 新增 | `getFolders()` - 获取文件夹列表 |
| 新增 | `createTag(name, color)` - 创建标签（可选） |

```javascript
// 修改后的 getBookmarks
async getBookmarks(tag = null, folderId = null) {
  const params = new URLSearchParams();
  if (tag) params.append('tag', tag);
  if (folderId) params.append('folderId', folderId);
  return this.request(`/bookmarks?${params.toString()}`);
}

// 修改后的 createBookmark
async createBookmark(data) {
  return this.request('/bookmarks', {
    method: 'POST',
    body: JSON.stringify({
      title: data.title,
      url: data.url,
      description: data.description,
      tags: data.tags,  // 标签名数组
      folderId: data.folderId,  // 新增
      visibility: data.visibility || 0
    })
  });
}
```

#### 4.1.2 后台脚本 (`src/extension/background/background.js`)

| 修改项 | 说明 |
|--------|------|
| `onBookmarkCreated` | 收集标签时考虑新的标签对象结构 |
| 新增 | 支持将浏览器书签文件夹映射到系统文件夹（可选） |

#### 4.1.3 弹窗界面 (`src/extension/popup/`)

**popup.js 修改**

| 修改项 | 说明 |
|--------|------|
| 标签输入 | 保持逗号分隔输入方式（后端会自动创建标签） |
| 新增 | 文件夹选择下拉框（可选功能） |

**popup.html 修改**

| 修改项 | 说明 |
|--------|------|
| 新增 | 文件夹选择器 UI（可选功能） |

#### 4.1.4 内容脚本 (`src/extension/content/content.js`)

| 修改项 | 说明 |
|--------|------|
| 搜索结果渲染 | 适配新的 Tag 对象结构，显示标签颜色 |

```javascript
// 修改后的搜索结果渲染
function renderSearchResult(bookmark) {
  const tagsHtml = bookmark.tags.map(tag => {
    const style = tag.color ? `background-color: ${tag.color}` : '';
    return `<span class="tag" style="${style}">${tag.name}</span>`;
  }).join('');

  return `
    <div class="search-result-item">
      <img src="${bookmark.icon || 'default-icon.png'}" alt="">
      <div class="info">
        <div class="title">${bookmark.title}</div>
        <div class="url">${bookmark.url}</div>
        <div class="tags">${tagsHtml}</div>
      </div>
    </div>
  `;
}
```

#### 4.1.5 新标签页 (`src/extension/newtab/index.html`)

| 修改项 | 说明 |
|--------|------|
| 书签卡片 | 适配新的 Tag 对象结构 |
| 标签显示 | 显示标签颜色 |
| 新增 | 文件夹导航（可选功能） |

### 4.2 插件修改优先级

| 优先级 | 任务 | 影响范围 |
|--------|------|----------|
| P0 | 修改 api.js 适配新接口 | 全局 |
| P0 | 修改 content.js 搜索结果渲染 | 全局搜索 |
| P0 | 修改 newtab 书签显示 | 新标签页 |
| P1 | 修改 popup 保存功能 | 快速保存 |
| P2 | 新增文件夹选择功能 | 新功能 |

---

## 五、API 接口变更说明

### 5.1 书签相关接口

| 接口 | 方法 | 变更 |
|------|------|------|
| `/api/bookmarks` | GET | 新增 `folderId` 查询参数 |
| `/api/bookmarks` | POST | 请求体新增 `folderId` 字段 |
| `/api/bookmarks/{id}` | PUT | 请求体新增 `folderId`、`updateFolder` 字段 |

### 5.2 标签相关接口

| 接口 | 方法 | 变更 |
|------|------|------|
| `/api/tags` | GET | 返回完整的 TagDto 对象（含 id, color, icon, order） |
| `/api/tags` | POST | **新增** - 创建标签 |
| `/api/tags/{id}` | GET | **新增** - 获取标签详情 |
| `/api/tags/{id}` | PUT | **新增** - 更新标签 |
| `/api/tags/{id}` | DELETE | 参数从标签名改为标签 ID |
| `/api/tags/merge` | POST | 请求体使用标签 ID 数组 |

### 5.3 响应数据结构变更

**BookmarkDto 响应示例**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "folderId": "660e8400-e29b-41d4-a716-446655440001",
  "title": "Example Site",
  "url": "https://example.com",
  "description": "An example website",
  "icon": "data:image/png;base64,...",
  "tags": [
    {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "name": "工作",
      "color": "#FF5733",
      "icon": "briefcase",
      "order": 1
    },
    {
      "id": "880e8400-e29b-41d4-a716-446655440003",
      "name": "技术",
      "color": "#33FF57",
      "icon": "code",
      "order": 2
    }
  ],
  "visitCount": 42,
  "lastVisitAt": "2024-12-25T10:30:00Z",
  "order": 1,
  "visibility": 0,
  "allowedDevices": null,
  "createdAt": "2024-12-01T00:00:00Z",
  "updatedAt": "2024-12-25T10:30:00Z"
}
```

---

## 六、数据表详细设计

### 6.1 users 表（用户）- 保持不变

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 用户ID |
| Email | string(200) | Unique, Not Null | 邮箱 |
| UserName | string(100) | Not Null | 用户名 |
| PasswordHash | string(500) | Not Null | 密码哈希 |
| Avatar | string(500) | Nullable | 头像URL |
| Role | int | Default 0 | 角色 |
| Status | int | Default 0 | 状态 |
| CreatedAt | DateTime | Not Null | 创建时间 |
| LastLoginAt | DateTime | Nullable | 最后登录 |

### 6.2 devices 表（设备）- 保持不变

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 设备ID |
| UserId | Guid | FK | 所属用户 |
| DeviceName | string(200) | Not Null | 设备名称 |
| DeviceType | string(200) | Not Null | 设备类型 |
| DeviceFingerprint | string(500) | Nullable | 设备指纹 |
| IsAdmin | bool | Default false | 管理员设备 |
| Status | int | Default 0 | 状态 |
| CreatedAt | DateTime | Not Null | 创建时间 |
| LastActiveAt | DateTime | Not Null | 最后活跃 |

### 6.3 folders 表（文件夹）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 文件夹ID |
| UserId | Guid | FK | 所属用户 |
| ParentId | Guid | FK, Nullable | 父文件夹 |
| Name | string(200) | Not Null | 名称 |
| Icon | string(100) | Nullable | 图标 |
| Order | int | Default 0 | 排序 |
| CreatedAt | DateTime | Not Null | 创建时间 |
| UpdatedAt | DateTime | Not Null | 更新时间 |

**索引：** `idx_folder_user_parent` (UserId, ParentId)

### 6.4 bookmarks 表（书签）- 重构

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 书签ID |
| UserId | Guid | FK | 所属用户 |
| FolderId | Guid | FK, Nullable | 所属文件夹 |
| Title | string(500) | Not Null | 标题 |
| Url | string(2000) | Not Null | URL |
| Description | string(2000) | Nullable | 描述 |
| Icon | string(MAX) | Nullable | 图标 |
| Order | int | Default 0 | 排序 |
| Visibility | int | Default 0 | 可见性 |
| VisitCount | int | Default 0 | 访问次数 |
| LastVisitAt | DateTime | Nullable | 最后访问 |
| CreatedAt | DateTime | Not Null | 创建时间 |
| UpdatedAt | DateTime | Not Null | 更新时间 |

**变更：** 移除 Tags、AllowedDevices；新增 FolderId

### 6.5 tags 表（标签）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 标签ID |
| UserId | Guid | FK | 所属用户 |
| Name | string(100) | Not Null | 名称 |
| Color | string(20) | Nullable | 颜色 |
| Icon | string(100) | Nullable | 图标 |
| Order | int | Default 0 | 排序 |
| CreatedAt | DateTime | Not Null | 创建时间 |

**索引：** `idx_tag_user_name` (UserId, Name) - Unique

### 6.6 bookmark_tags 表（书签-标签关联）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 关联ID |
| BookmarkId | Guid | FK | 书签ID |
| TagId | Guid | FK | 标签ID |
| CreatedAt | DateTime | Not Null | 创建时间 |

**索引：** `idx_bookmark_tag_unique` (BookmarkId, TagId) - Unique

### 6.7 bookmark_device_permissions 表（设备权限）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 权限ID |
| BookmarkId | Guid | FK | 书签ID |
| DeviceId | Guid | FK | 设备ID |
| CreatedAt | DateTime | Not Null | 创建时间 |

**索引：** `idx_permission_unique` (BookmarkId, DeviceId) - Unique

### 6.8 collections 表（收藏集合）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 集合ID |
| UserId | Guid | FK | 所属用户 |
| Name | string(200) | Not Null | 名称 |
| Description | string(500) | Nullable | 描述 |
| Icon | string(100) | Nullable | 图标 |
| Color | string(20) | Nullable | 主题色 |
| IsPublic | bool | Default false | 是否公开 |
| Order | int | Default 0 | 排序 |
| CreatedAt | DateTime | Not Null | 创建时间 |
| UpdatedAt | DateTime | Not Null | 更新时间 |

### 6.9 collection_bookmarks 表（集合-书签关联）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 关联ID |
| CollectionId | Guid | FK | 集合ID |
| BookmarkId | Guid | FK | 书签ID |
| Order | int | Default 0 | 排序 |
| CreatedAt | DateTime | Not Null | 添加时间 |

### 6.10 bookmark_shares 表（分享链接）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 分享ID |
| UserId | Guid | FK | 创建者 |
| ShareCode | string(50) | Unique | 分享码 |
| ShareType | int | Not Null | 类型 |
| TargetId | Guid | Not Null | 目标ID |
| Title | string(200) | Nullable | 标题 |
| Password | string(100) | Nullable | 密码 |
| ViewCount | int | Default 0 | 查看次数 |
| MaxViews | int | Nullable | 最大查看 |
| ExpiresAt | DateTime | Nullable | 过期时间 |
| IsActive | bool | Default true | 是否启用 |
| CreatedAt | DateTime | Not Null | 创建时间 |

### 6.11 bookmark_visits 表（访问历史）- 新增

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | Guid | PK | 记录ID |
| UserId | Guid | FK | 用户ID |
| BookmarkId | Guid | FK | 书签ID |
| DeviceId | Guid | FK, Nullable | 设备ID |
| VisitedAt | DateTime | Not Null | 访问时间 |

---

## 七、实体关系图

```
┌─────────────┐
│   users     │
└──────┬──────┘
       │
       │ 1:N
       ├────────────────┬────────────────┬────────────────┬────────────────┐
       │                │                │                │                │
       ▼                ▼                ▼                ▼                ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│  devices    │  │  folders    │  │    tags     │  │ collections │  │   shares    │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └─────────────┘
       │                │ 1:N            │                │
       │                │ (self-ref)     │                │
       │                ▼                │                │
       │         ┌─────────────┐         │                │
       │         │  bookmarks  │◄────────┘                │
       │         └──────┬──────┘                          │
       │                │                                 │
       │                │ N:M                             │ N:M
       │                ├─────────────────────────────────┤
       │                │                                 │
       │                ▼                                 ▼
       │         ┌─────────────┐                   ┌─────────────┐
       │         │bookmark_tags│                   │ collection_ │
       │         └─────────────┘                   │  bookmarks  │
       │
       ├─────────────────────────────────────────────────┐
       │                                                 │
       ▼                                                 ▼
┌─────────────────────┐                          ┌─────────────┐
│ bookmark_device_    │                          │  bookmark_  │
│    permissions      │                          │   visits    │
└─────────────────────┘                          └─────────────┘
```

---

## 八、重构进度跟踪

### 8.1 后端重构（已完成 ✅）

- [x] 修改 Bookmark.cs 实体
- [x] 新增 Folder.cs 实体
- [x] 新增 Tag.cs 实体
- [x] 新增 BookmarkTag.cs 实体
- [x] 新增 BookmarkDevicePermission.cs 实体
- [x] 新增 Collection.cs 实体
- [x] 新增 CollectionBookmark.cs 实体
- [x] 新增 BookmarkShare.cs 实体
- [x] 新增 BookmarkVisit.cs 实体
- [x] 新增 ShareType.cs 枚举
- [x] 修改 FreeSqlSetup.cs 注册新实体
- [x] 重构 BookmarkService.cs
- [x] 重构 TagService.cs
- [x] 更新 DTO 类
- [x] 更新控制器
- [x] 构建验证通过

### 8.2 前端重构（已完成 ✅）

- [x] 修改类型定义 (types/index.ts)
  - Tag 接口新增 id、color、icon、order 字段
  - Bookmark.tags 从 string[] 改为 Tag[]
  - Bookmark.lastVisitTime 改名为 lastVisitAt
  - 新增 folderId 字段
  - 新增 Folder、Collection 接口
- [x] 修改 API 层 (api/bookmark.ts, api/tag.ts)
  - getBookmarks 新增 folderId 参数
  - 新增文件夹相关 API
  - 标签 API 改用 ID
- [x] 修改 Store 层 (stores/bookmark.ts, stores/tag.ts)
  - 新增 folders、currentFolderId 状态
  - 新增文件夹操作方法
  - 标签操作改用 ID
- [x] 修改 BookmarkList 组件
  - 标签显示改为 tag.name
  - 支持显示标签颜色
- [x] 修改 BookmarkEditor 组件
  - 适配新的标签对象结构
- [x] 新增文件夹相关组件
  - FolderTree.vue - 文件夹树形组件
- [x] 新增标签管理组件
  - TagBadge.vue - 带颜色的标签徽章组件
  - TagManager.vue - 标签管理弹窗
- [x] 修改 HomeView.vue
  - 添加文件夹导航
  - 标签显示颜色
  - 面包屑导航
  - 标签管理入口
- [x] 构建验证通过

### 8.3 浏览器插件重构（待开始）

- [ ] 修改 shared/api.js
- [ ] 修改 content/content.js 搜索结果渲染
- [ ] 修改 newtab/index.html 书签显示
- [ ] 修改 popup/popup.js 保存功能

---

## 九、注意事项

1. **数据迁移**：本次重构不考虑旧数据迁移，直接使用新表结构
2. **向后兼容**：API 响应格式已变更，前端和插件必须同步更新
3. **标签创建**：创建书签时传入的标签名会自动创建不存在的标签
4. **级联删除**：删除用户时需级联删除所有关联数据
5. **性能考虑**：bookmark_visits 表数据量可能很大，考虑定期清理

---

## 十、版本信息

- 文档版本：v2.1
- 创建日期：2024-12-25
- 最后更新：2024-12-25
- 作者：Claude Code
- 更新说明：完成前端重构
