# 蜂鸟Pro 系统设计文档 v2.0

## 一、系统概述

蜂鸟Pro 是一个 Cursor 账号管理与智能换号工具，支持双账号池（Auto/Pro）、无感换号、用量监控等功能。

### 1.1 核心功能

| 功能 | 描述 |
|------|------|
| 双账号池 | Auto池（按时间计费）+ Pro池（按积分计费） |
| 无感换号 | 注入代码实现不重启切换账号 |
| 用量监控 | 实时获取 Cursor 官方用量数据 |
| 智能换号 | 根据用量自动触发换号 |
| 密钥合并 | 多个密钥合并到主密钥，累加资源 |

---

## 二、数据模型设计

### 2.1 账号表 (cursor_accounts)

```sql
CREATE TABLE cursor_accounts (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(255) NOT NULL COMMENT '账号邮箱',
    token TEXT NOT NULL COMMENT '认证Token (user_id::jwt)',
    password VARCHAR(255) COMMENT '账号密码(可选)',

    -- 状态管理
    status ENUM('pending', 'analyzing', 'available', 'in_use', 'exhausted', 'invalid', 'disabled')
           DEFAULT 'pending' COMMENT '账号状态',

    -- 账号类型 (从Cursor API自动分析得出)
    account_type ENUM('free_trial', 'pro', 'free', 'business', 'unknown')
                 DEFAULT 'unknown' COMMENT '账号类型',

    -- 用量信息 (从Cursor API获取)
    membership_type VARCHAR(50) COMMENT '会员类型原始值',
    billing_cycle_start DATETIME COMMENT '计费周期开始',
    billing_cycle_end DATETIME COMMENT '计费周期结束',
    trial_days_remaining INT DEFAULT 0 COMMENT '试用剩余天数',

    -- 用量统计
    usage_limit INT DEFAULT 0 COMMENT '用量上限',
    usage_used INT DEFAULT 0 COMMENT '已用用量',
    usage_remaining INT DEFAULT 0 COMMENT '剩余用量',
    usage_percent DECIMAL(5,2) DEFAULT 0 COMMENT '用量百分比',

    -- 详细用量 (从聚合API获取)
    total_requests INT DEFAULT 0 COMMENT '总请求次数',
    total_input_tokens BIGINT DEFAULT 0 COMMENT '总输入Token',
    total_output_tokens BIGINT DEFAULT 0 COMMENT '总输出Token',
    total_cost_cents DECIMAL(10,2) DEFAULT 0 COMMENT '总花费(美分)',

    -- 锁定信息
    locked_by_key_id INT COMMENT '被哪个激活码锁定',
    locked_at DATETIME COMMENT '锁定时间',

    -- 分析信息
    last_analyzed_at DATETIME COMMENT '最后分析时间',
    analyze_error VARCHAR(500) COMMENT '分析错误信息',

    -- 元数据
    remark VARCHAR(500) COMMENT '备注',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    INDEX idx_status (status),
    INDEX idx_account_type (account_type),
    INDEX idx_locked_by (locked_by_key_id)
);
```

### 2.2 账号状态流转

```
pending (待分析)
    ↓ 后台分析任务
analyzing (分析中)
    ↓ 分析成功
available (可用)
    ↓ 被激活码锁定
in_use (使用中)
    ↓ 用量耗尽 / 手动释放
exhausted (已耗尽) / available (可用)

异常状态:
- invalid: Token无效/过期
- disabled: 管理员禁用
```

### 2.3 激活码表 (activation_keys)

```sql
CREATE TABLE activation_keys (
    id INT PRIMARY KEY AUTO_INCREMENT,
    `key` VARCHAR(64) NOT NULL UNIQUE COMMENT '激活码',

    -- 状态
    status ENUM('unused', 'active', 'expired', 'disabled') DEFAULT 'unused' COMMENT '状态',

    -- 套餐类型
    membership_type ENUM('auto', 'pro') DEFAULT 'pro' COMMENT '套餐类型',

    -- 密钥合并 (支持多密钥合并到主密钥)
    master_key_id INT COMMENT '主密钥ID (如果已合并到其他密钥)',
    merged_count INT DEFAULT 0 COMMENT '已合并的子密钥数量',
    merged_at DATETIME COMMENT '合并时间',

    -- 设备绑定
    device_id VARCHAR(255) COMMENT '绑定的设备ID',

    -- ===== Auto密钥专属字段 =====
    duration_days INT DEFAULT 30 COMMENT '该密钥贡献的天数',
    expire_at DATETIME COMMENT '到期时间 (首次激活时计算)',

    -- ===== Pro密钥专属字段 =====
    quota_contribution INT DEFAULT 500 COMMENT '该密钥贡献的积分',
    quota INT DEFAULT 500 COMMENT '总积分 (主密钥累加值)',
    quota_used INT DEFAULT 0 COMMENT '已用积分',

    -- ===== 无感换号 =====
    seamless_enabled TINYINT(1) DEFAULT 0 COMMENT '是否启用无感换号',
    current_account_id INT COMMENT '当前使用的账号ID',

    -- ===== 统计 =====
    switch_count INT DEFAULT 0 COMMENT '总换号次数',
    last_switch_at DATETIME COMMENT '最后换号时间',

    -- ===== 设备限制 =====
    max_devices INT DEFAULT 2 COMMENT '最大设备数',

    -- 激活信息
    first_activated_at DATETIME COMMENT '首次激活时间',
    last_active_at DATETIME COMMENT '最后活跃时间',

    -- 备注
    remark VARCHAR(500) COMMENT '备注',

    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    INDEX idx_status (status),
    INDEX idx_membership_type (membership_type),
    INDEX idx_device_id (device_id),
    INDEX idx_master_key_id (master_key_id),
    FOREIGN KEY (master_key_id) REFERENCES activation_keys(id),
    FOREIGN KEY (current_account_id) REFERENCES cursor_accounts(id)
);
```

### 2.4 设备绑定表 (key_devices)

```sql
CREATE TABLE key_devices (
    id INT PRIMARY KEY AUTO_INCREMENT,
    key_id INT NOT NULL COMMENT '激活码ID',
    device_id VARCHAR(255) NOT NULL COMMENT '设备标识',
    device_name VARCHAR(255) COMMENT '设备名称',
    platform VARCHAR(50) COMMENT '平台: windows/macos/linux',
    last_active_at DATETIME COMMENT '最后活跃时间',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

    UNIQUE KEY uk_key_device (key_id, device_id),
    FOREIGN KEY (key_id) REFERENCES activation_keys(id)
);
```

### 2.5 使用日志表 (usage_logs)

```sql
CREATE TABLE usage_logs (
    id INT PRIMARY KEY AUTO_INCREMENT,
    key_id INT NOT NULL COMMENT '激活码ID',
    account_id INT COMMENT '账号ID',

    action ENUM('activate', 'verify', 'enable_seamless', 'disable_seamless',
                'switch', 'auto_switch', 'release', 'merge') NOT NULL COMMENT '操作类型',

    success TINYINT(1) DEFAULT 1 COMMENT '是否成功',
    message VARCHAR(500) COMMENT '消息',

    -- 请求信息
    ip_address VARCHAR(50),
    user_agent VARCHAR(500),
    device_id VARCHAR(255),

    -- 用量快照 (换号时记录)
    usage_snapshot JSON COMMENT '用量快照',

    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

    INDEX idx_key_id (key_id),
    INDEX idx_action (action),
    INDEX idx_created_at (created_at)
);
```

### 2.6 全局设置表 (global_settings)

```sql
CREATE TABLE global_settings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    `key` VARCHAR(100) NOT NULL UNIQUE COMMENT '设置键',
    value VARCHAR(500) NOT NULL COMMENT '设置值',
    value_type ENUM('string', 'int', 'float', 'bool', 'json') DEFAULT 'string',
    description VARCHAR(500) COMMENT '描述',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 默认设置
INSERT INTO global_settings (`key`, value, value_type, description) VALUES
('auto_switch_threshold', '98', 'int', 'Auto池自动换号阈值(用量百分比)'),
('pro_switch_threshold', '98', 'int', 'Pro池自动换号阈值(用量百分比)'),
('account_analyze_interval', '300', 'int', '账号分析间隔(秒)'),
('max_switch_per_day', '50', 'int', '每日最大换号次数'),
('auto_daily_switches', '999', 'int', 'Auto密钥每日换号次数限制'),
('pro_quota_per_switch', '1', 'int', 'Pro密钥每次换号消耗积分');
```

---

## 三、业务流程设计

### 3.1 账号添加与分析流程

```
┌─────────────────────────────────────────────────────────────┐
│                    管理员添加账号                            │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 保存账号，状态 = pending                                  │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 后台定时任务 (每5分钟扫描 pending/available 状态账号)      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 调用 Cursor API 分析账号                                  │
│    ├─ GET /api/usage-summary                                │
│    │   → membershipType, usageLimit, usageUsed              │
│    │   → daysRemainingOnTrial, billingCycle                 │
│    │                                                        │
│    └─ POST /api/dashboard/get-aggregated-usage-events       │
│        → totalRequests, totalCostCents                      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 更新账号信息                                              │
│    ├─ account_type = 根据 membershipType 判断               │
│    ├─ 更新所有用量字段                                       │
│    ├─ last_analyzed_at = NOW()                              │
│    └─ status = available (如果用量未耗尽)                    │
│              = exhausted (如果用量已耗尽)                    │
│              = invalid (如果Token无效)                       │
└─────────────────────────────────────────────────────────────┘
```

### 3.2 密钥激活流程

```
┌─────────────────────────────────────────────────────────────┐
│                    用户输入激活码                            │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 验证激活码                                                │
│    ├─ 检查激活码是否存在                                     │
│    ├─ 检查状态是否为 unused 或 active                        │
│    └─ 检查是否过期 (Auto: expire_at, Pro: quota剩余)         │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 处理设备绑定                                              │
│    ├─ 检查当前设备数是否超过 max_devices                     │
│    ├─ 如果是新设备，添加到 key_devices                       │
│    └─ 更新 last_active_at                                   │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 首次激活处理                                              │
│    ├─ 如果 first_activated_at 为空:                         │
│    │   ├─ Auto: 计算 expire_at = NOW() + duration_days      │
│    │   └─ 设置 first_activated_at = NOW()                   │
│    └─ 更新 status = active                                  │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 返回激活结果 (不分配账号!)                                │
│    {                                                        │
│      success: true,                                         │
│      membership_type: "auto" / "pro",                       │
│      expire_at: "2025-12-25 18:00:00",  // Auto             │
│      quota: 500, quota_used: 0,          // Pro             │
│      seamless_enabled: false                                │
│    }                                                        │
└─────────────────────────────────────────────────────────────┘
```

### 3.3 启用无感换号流程

```
┌─────────────────────────────────────────────────────────────┐
│                用户点击"启用无感换号"                         │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 前端: 注入代码到 Cursor workbench.js                      │
│    ├─ 检查是否有写入权限                                     │
│    ├─ 备份原文件                                            │
│    └─ 注入换号代码                                          │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 前端: 调用后端 API 启用无感                               │
│    POST /api/client/enable-seamless                         │
│    { key, device_id }                                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 后端: 分配账号                                            │
│    ├─ 根据密钥类型选择账号池:                                │
│    │   ├─ Auto密钥 → 优先 free_trial 类型账号               │
│    │   └─ Pro密钥 → 优先 pro 类型账号                       │
│    ├─ 从 available 状态账号中选择用量最低的                  │
│    ├─ 锁定账号: locked_by_key_id = key.id, status = in_use  │
│    └─ 更新密钥: current_account_id, seamless_enabled = 1    │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 返回账号信息                                              │
│    {                                                        │
│      success: true,                                         │
│      account: {                                             │
│        email: "xxx@gmail.com",                              │
│        token: "user_id::jwt_token",                         │
│        membership_type: "free_trial",                       │
│        trial_days_remaining: 6,                             │
│        usage_percent: 20,                                   │
│        total_requests: 201,                                 │
│        total_cost_usd: 12.63                                │
│      }                                                      │
│    }                                                        │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 5. 前端: 显示账号用量模块，提示重启 Cursor                   │
└─────────────────────────────────────────────────────────────┘
```

### 3.4 换号流程 (手动/自动)

```
┌─────────────────────────────────────────────────────────────┐
│            手动换号 / 自动换号 (用量超阈值)                   │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 检查换号条件                                              │
│    ├─ 密钥是否有效                                          │
│    ├─ 是否启用了无感换号                                     │
│    ├─ Pro密钥: 检查剩余积分是否足够                          │
│    └─ 检查今日换号次数是否超限                               │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 释放当前账号                                              │
│    ├─ 获取当前账号用量快照 (用于日志)                        │
│    ├─ 判断账号状态:                                         │
│    │   ├─ 用量 < 90% → status = available                   │
│    │   └─ 用量 >= 90% → status = exhausted                  │
│    └─ 清除锁定: locked_by_key_id = NULL                     │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 分配新账号 (同启用无感流程)                               │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 更新统计                                                  │
│    ├─ Pro密钥: quota_used += 1                              │
│    ├─ switch_count += 1                                     │
│    ├─ last_switch_at = NOW()                                │
│    └─ 记录日志到 usage_logs                                 │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 5. 返回新账号信息                                            │
└─────────────────────────────────────────────────────────────┘
```

### 3.5 密钥合并流程

```
┌─────────────────────────────────────────────────────────────┐
│              用户输入新密钥到已激活的设备                     │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 检查合并条件                                              │
│    ├─ 新密钥状态必须是 unused                                │
│    ├─ 新密钥类型必须与主密钥相同 (Auto+Auto / Pro+Pro)       │
│    └─ 检查主密钥是否已被合并过 (已合并的不能再当主密钥)       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 执行合并                                                  │
│    ├─ 新密钥: master_key_id = 主密钥ID, merged_at = NOW()   │
│    ├─ 新密钥: status = active                               │
│    │                                                        │
│    ├─ 主密钥 (Auto): expire_at += 新密钥.duration_days      │
│    └─ 主密钥 (Pro): quota += 新密钥.quota_contribution       │
│                                                             │
│    └─ 主密钥: merged_count += 1                             │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 返回合并结果                                              │
│    {                                                        │
│      success: true,                                         │
│      message: "密钥已合并",                                  │
│      new_expire_at / new_quota: ...                         │
│    }                                                        │
└─────────────────────────────────────────────────────────────┘
```

---

## 四、API 接口设计

### 4.1 客户端 API (/api/client/*)

#### 4.1.1 验证/激活密钥
```
POST /api/client/activate
Request:
{
    "key": "XXXX-XXXX-XXXX",
    "device_id": "machine_id_hash"
}

Response (成功):
{
    "success": true,
    "data": {
        "key": "XXXX-XXXX-XXXX",
        "membership_type": "auto",  // auto | pro
        "status": "active",

        // Auto密钥
        "expire_at": "2025-12-25T18:00:00Z",
        "days_remaining": 7,

        // Pro密钥
        "quota": 500,
        "quota_used": 50,
        "quota_remaining": 450,

        // 无感状态
        "seamless_enabled": false,
        "current_account": null
    }
}

Response (失败):
{
    "success": false,
    "error": "激活码无效",
    "code": "INVALID_KEY"
}
```

#### 4.1.2 启用无感换号
```
POST /api/client/enable-seamless
Request:
{
    "key": "XXXX-XXXX-XXXX",
    "device_id": "machine_id_hash"
}

Response:
{
    "success": true,
    "data": {
        "account": {
            "email": "user@gmail.com",
            "token": "user_id::jwt_token",
            "account_type": "free_trial",
            "membership_type": "free_trial",
            "trial_days_remaining": 6,
            "usage_percent": 20.5,
            "total_requests": 201,
            "total_cost_usd": 12.63
        }
    }
}
```

#### 4.1.3 禁用无感换号
```
POST /api/client/disable-seamless
Request:
{
    "key": "XXXX-XXXX-XXXX"
}

Response:
{
    "success": true,
    "message": "无感换号已禁用"
}
```

#### 4.1.4 手动换号
```
POST /api/client/switch
Request:
{
    "key": "XXXX-XXXX-XXXX"
}

Response:
{
    "success": true,
    "data": {
        "old_account": "old@gmail.com",
        "new_account": {
            "email": "new@gmail.com",
            "token": "user_id::jwt_token",
            ...
        },
        "switch_count": 5,
        "quota_remaining": 495  // Pro密钥
    }
}
```

#### 4.1.5 获取状态
```
GET /api/client/status?key=XXXX-XXXX-XXXX

Response:
{
    "success": true,
    "data": {
        "key_info": {
            "membership_type": "auto",
            "status": "active",
            "expire_at": "2025-12-25T18:00:00Z",
            "days_remaining": 7,
            "seamless_enabled": true,
            "switch_count": 3
        },
        "account_info": {  // 仅当 seamless_enabled=true
            "email": "user@gmail.com",
            "account_type": "free_trial",
            "trial_days_remaining": 6,
            "usage_percent": 20.5,
            "total_requests": 201,
            "total_cost_usd": 12.63,
            "last_analyzed_at": "2025-12-18T14:12:35Z"
        }
    }
}
```

#### 4.1.6 获取账号用量 (实时)
```
GET /api/client/account-usage?key=XXXX-XXXX-XXXX&refresh=true

Response:
{
    "success": true,
    "data": {
        "email": "user@gmail.com",
        "membership_type": "free_trial",
        "trial_days_remaining": 6,
        "billing_cycle": {
            "start": "2025-12-15T00:00:00Z",
            "end": "2026-01-15T00:00:00Z"
        },
        "usage": {
            "limit": 1000,
            "used": 201,
            "remaining": 799,
            "percent": 20.1
        },
        "cost": {
            "total_requests": 201,
            "total_input_tokens": 346883,
            "total_output_tokens": 45356,
            "total_cost_usd": 12.63
        },
        "updated_at": "2025-12-18T14:12:35Z"
    }
}
```

### 4.2 管理后台 API (/api/admin/*)

#### 4.2.1 账号管理
```
GET    /api/admin/accounts              # 账号列表
POST   /api/admin/accounts              # 添加账号 (只需token)
GET    /api/admin/accounts/{id}         # 账号详情
PUT    /api/admin/accounts/{id}         # 更新账号
DELETE /api/admin/accounts/{id}         # 删除账号
POST   /api/admin/accounts/{id}/analyze # 手动分析账号
POST   /api/admin/accounts/batch        # 批量添加账号
```

#### 4.2.2 激活码管理
```
GET    /api/admin/keys                  # 激活码列表
POST   /api/admin/keys/generate         # 生成激活码
GET    /api/admin/keys/{id}             # 激活码详情
PUT    /api/admin/keys/{id}             # 更新激活码
DELETE /api/admin/keys/{id}             # 删除激活码
POST   /api/admin/keys/{id}/extend      # 延期/加积分
```

---

## 五、前端界面设计

### 5.1 控制面板布局

```
┌─────────────────────────────────────────────────────────────┐
│ 🔐 软件授权                                         已授权  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌───────────────────┐  ┌───────────────────┐              │
│  │     🌿 Auto       │  │     ⚡ Pro        │              │
│  │  基础模型·无限换号 │  │  高级模型·积分制  │              │
│  │      已激活       │  │      已激活       │              │
│  └───────────────────┘  └───────────────────┘              │
│                                                             │
│  [请输入CDK激活码                              ]  [激活]    │
│                                                             │
│  ┌─ AUTO 密钥 ──────────┐  ┌─ PRO 密钥 ──────────┐        │
│  │ HIOR03M0GT8VDTL****  │  │ LAXFY1EY7QZJ9C3L****│        │
│  │ 到期: 2025/12/19     │  │ 积分: 450/500       │        │
│  │ 18:49:36             │  │                     │        │
│  │ [清除]               │  │ [清除]              │        │
│  └──────────────────────┘  └─────────────────────┘        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ ⚡ 无感换号                                         已启用  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  当前账号      user123@gmail.com                           │
│                                                             │
│  使用池        ● Auto池  ○ Pro池                           │
│                                                             │
│  免魔法模式 PRO                              [====○    ]   │
│                                                             │
│  [    一键换号 (Auto无限/Pro扣1积分)    ]                   │
│                                                             │
│  [重置机器码]                    [禁用无感换号]             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 📊 账号用量                                           [🔄]  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────┬─────────────────┐                     │
│  │ 会员类型        │ 免费试用        │                     │
│  ├─────────────────┼─────────────────┤                     │
│  │ 试用剩余        │ 6 天            │                     │
│  ├─────────────────┼─────────────────┤                     │
│  │ 请求次数        │ 201 次          │                     │
│  ├─────────────────┼─────────────────┤                     │
│  │ 已用额度        │ $12.63          │                     │
│  ├─────────────────┼─────────────────┤                     │
│  │ 用量百分比      │ ████░░░░ 20%    │                     │
│  └─────────────────┴─────────────────┘                     │
│                                                             │
│  更新于 14:12:35                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 📢 公告                                              通知   │
├─────────────────────────────────────────────────────────────┤
│ 欢迎使用蜂鸟Pro                                            │
│ 感谢使用蜂鸟Pro!                                           │
│                                                             │
│ 如有问题请联系客服。                                        │
│                                           2024/12/17 00:00 │
└─────────────────────────────────────────────────────────────┘
```

### 5.2 状态显示规则

| 条件 | 显示内容 |
|------|----------|
| 未激活任何密钥 | "请先激活授权码", 启用无感按钮禁用 |
| 已激活Auto | 显示Auto密钥卡片, 到期时间 |
| 已激活Pro | 显示Pro密钥卡片, 积分 xxx/xxx |
| 已激活但未启用无感 | "账号用量"模块隐藏 |
| 已启用无感 | 显示当前账号邮箱, 显示"账号用量"模块 |

---

## 六、注入代码设计

### 6.1 注入位置
```
Cursor安装目录/resources/app/out/vs/workbench/workbench.desktop.main.js
```

### 6.2 注入代码功能
```javascript
// 注入的代码 (伪代码)
(function() {
    const API_BASE = 'https://api.aicode.edu.pl';
    const CHECK_INTERVAL = 60000;  // 每60秒检查一次

    // 从 localStorage 读取配置
    const config = JSON.parse(localStorage.getItem('hummingbird_config') || '{}');

    // 定时检查用量
    setInterval(async () => {
        if (!config.enabled) return;

        try {
            // 获取用量
            const usage = await fetch(`${API_BASE}/api/client/account-usage?key=${config.key}`);
            const data = await usage.json();

            // 检查是否需要换号
            if (data.usage.percent >= config.threshold) {
                // 自动换号
                const switchRes = await fetch(`${API_BASE}/api/client/switch`, {
                    method: 'POST',
                    body: JSON.stringify({ key: config.key })
                });
                const newAccount = await switchRes.json();

                // 更新本地 Token
                if (newAccount.success) {
                    updateLocalToken(newAccount.data.new_account.token);
                }
            }
        } catch (e) {
            console.error('[HummingbirdPro] Check failed:', e);
        }
    }, CHECK_INTERVAL);

    function updateLocalToken(token) {
        // 更新 Cursor 的认证存储
        // ...
    }
})();
```

---

## 七、后台定时任务

### 7.1 账号分析任务
```python
# 每5分钟执行一次
async def analyze_accounts_task():
    """分析待处理和可用状态的账号"""

    # 获取需要分析的账号
    accounts = db.query(CursorAccount).filter(
        CursorAccount.status.in_(['pending', 'available']),
        or_(
            CursorAccount.last_analyzed_at == None,
            CursorAccount.last_analyzed_at < datetime.now() - timedelta(minutes=30)
        )
    ).limit(10).all()

    for account in accounts:
        try:
            # 调用 Cursor API
            usage_data = await cursor_api.get_usage_summary(account.token)
            aggregated = await cursor_api.get_aggregated_usage(account.token)

            # 更新账号信息
            account.account_type = map_membership_type(usage_data['membershipType'])
            account.membership_type = usage_data['membershipType']
            account.trial_days_remaining = usage_data.get('daysRemainingOnTrial', 0)
            account.usage_limit = usage_data['individualUsage']['plan']['limit']
            account.usage_used = usage_data['individualUsage']['plan']['used']
            account.usage_percent = (account.usage_used / account.usage_limit * 100) if account.usage_limit > 0 else 0
            account.total_requests = aggregated.get('totalRequests', 0)
            account.total_cost_cents = aggregated.get('totalCostCents', 0)
            account.last_analyzed_at = datetime.now()

            # 更新状态
            if account.usage_percent >= 95:
                account.status = AccountStatus.EXHAUSTED
            elif account.status == AccountStatus.PENDING:
                account.status = AccountStatus.AVAILABLE

        except TokenInvalidError:
            account.status = AccountStatus.INVALID
            account.analyze_error = "Token无效或已过期"
        except Exception as e:
            account.analyze_error = str(e)

    db.commit()
```

---

## 八、错误码定义

| 错误码 | 描述 |
|--------|------|
| INVALID_KEY | 激活码无效 |
| KEY_EXPIRED | 激活码已过期 |
| KEY_DISABLED | 激活码已禁用 |
| QUOTA_EXCEEDED | 积分不足 |
| DEVICE_LIMIT | 设备数超限 |
| NO_AVAILABLE_ACCOUNT | 无可用账号 |
| SEAMLESS_NOT_ENABLED | 未启用无感换号 |
| SWITCH_LIMIT_EXCEEDED | 换号次数超限 |
| ACCOUNT_LOCKED | 账号已被锁定 |
| TOKEN_INVALID | Token无效 |

---

## 九、部署配置

### 9.1 环境变量
```bash
# 数据库
USE_SQLITE=false
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=cursorpro
DB_PASSWORD=xxx
DB_NAME=cursorpro

# JWT
SECRET_KEY=your-secret-key
ACCESS_TOKEN_EXPIRE_MINUTES=10080

# 管理员
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your-password

# API
API_TOKEN=your-api-token
```

### 9.2 依赖
```
fastapi
uvicorn
sqlalchemy
pymysql
pydantic
httpx
apscheduler
```

---

## 十、开发计划

### Phase 1: 后端重构
1. [ ] 更新数据模型 (models.py)
2. [ ] 实现 Cursor API 服务 (cursor_usage_service.py)
3. [ ] 重写账号服务 (account_service.py)
4. [ ] 重写客户端 API (client.py)
5. [ ] 添加定时任务 (tasks.py)

### Phase 2: 前端优化
1. [ ] 重构 panel.html 界面
2. [ ] 修复状态显示逻辑
3. [ ] 添加账号用量模块
4. [ ] 优化错误提示

### Phase 3: 测试与部署
1. [ ] 单元测试
2. [ ] 集成测试
3. [ ] 部署到生产环境
