# 蜂鸟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. [ ] 部署到生产环境