蜂鸟Pro v2.0.1 - 基础框架版本 (待完善)

## 当前状态
- 插件界面已完成重命名 (cursorpro → hummingbird)
- 双账号池 UI 已实现 (Auto/Pro 卡片)
- 后端已切换到 MySQL 数据库
- 添加了 Cursor 官方用量 API 文档

## 已知问题 (待修复)
1. 激活时检查账号导致无账号时激活失败
2. 未启用无感换号时不应获取账号
3. 账号用量模块不显示 (seamless 未启用时应隐藏)
4. 积分显示为 0 (后端未正确返回)
5. Auto/Pro 双密钥逻辑混乱,状态不同步
6. 账号添加后无自动分析功能

## 下一版本计划
- 重构数据模型,优化账号状态管理
- 实现 Cursor API 自动分析账号
- 修复激活流程,不依赖账号
- 启用无感时才分配账号
- 完善账号用量实时显示

## 文件说明
- docs/系统设计文档.md - 完整架构设计
- cursor 官方用量接口.md - Cursor API 文档
- 参考计费/ - Vibeviewer 开源项目参考

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ccdojox-crypto
2025-12-18 11:21:52 +08:00
parent f310ca7b97
commit 73a71f198f
202 changed files with 19142 additions and 252 deletions

View File

@@ -587,6 +587,101 @@ async def delete_key(
return {"message": "删除成功"}
@router.post("/keys/{key_id}/revoke")
async def revoke_key(
key_id: int,
db: Session = Depends(get_db),
current_user: dict = Depends(get_current_user)
):
"""撤销激活码(从主密钥扣除资源)"""
success, message = KeyService.revoke_key(db, key_id)
if not success:
raise HTTPException(status_code=400, detail=message)
return {"success": True, "message": message}
@router.get("/keys/by-device/{device_id}")
async def get_keys_by_device(
device_id: str,
db: Session = Depends(get_db),
current_user: dict = Depends(get_current_user)
):
"""获取设备的所有密钥(管理后台用)"""
keys_info = KeyService.get_device_keys(db, device_id)
result = {
"device_id": device_id,
"auto": None,
"pro": None
}
# Auto 密钥组
if keys_info["auto"]:
auto_data = keys_info["auto"]
master = auto_data["master"]
merged_keys = auto_data["merged_keys"]
all_keys = [{
"id": master.id,
"key": master.key,
"is_master": True,
"status": master.status.value,
"duration_days": master.duration_days,
"activated_at": master.first_activated_at.strftime("%Y-%m-%d %H:%M:%S") if master.first_activated_at else None
}]
for k in merged_keys:
all_keys.append({
"id": k.id,
"key": k.key,
"is_master": False,
"status": k.status.value,
"duration_days": k.duration_days,
"merged_at": k.merged_at.strftime("%Y-%m-%d %H:%M:%S") if k.merged_at else None
})
result["auto"] = {
"total_keys": len(all_keys),
"expire_at": master.expire_at.strftime("%Y-%m-%d %H:%M:%S") if master.expire_at else None,
"current_account": master.current_account.email if master.current_account else None,
"keys": all_keys
}
# Pro 密钥组
if keys_info["pro"]:
pro_data = keys_info["pro"]
master = pro_data["master"]
merged_keys = pro_data["merged_keys"]
all_keys = [{
"id": master.id,
"key": master.key,
"is_master": True,
"status": master.status.value,
"quota_contribution": master.quota_contribution,
"activated_at": master.first_activated_at.strftime("%Y-%m-%d %H:%M:%S") if master.first_activated_at else None
}]
for k in merged_keys:
all_keys.append({
"id": k.id,
"key": k.key,
"is_master": False,
"status": k.status.value,
"quota_contribution": k.quota_contribution,
"merged_at": k.merged_at.strftime("%Y-%m-%d %H:%M:%S") if k.merged_at else None
})
result["pro"] = {
"total_keys": len(all_keys),
"quota": pro_data["quota"],
"quota_used": pro_data["quota_used"],
"quota_remaining": pro_data["quota_remaining"],
"current_account": master.current_account.email if master.current_account else None,
"keys": all_keys
}
return result
@router.get("/keys/{key_id}/usage-info")
async def get_key_usage_info(
key_id: int,