feat(pool,provider_ops): 扩展批量操作支持代理设置,优化签到缓存与余额刷新

- pool batch-action 新增 clear_proxy/set_proxy 操作,前端统一使用
  batch-action API 替代逐个调用,批量上限从 100 提升至 2000
- batch-action 删除操作后执行 key 删除副作用(run_delete_key_side_effects)
- BalanceAction 签到增加 6 小时缓存冷却,同一 host 避免重复签到
- 异步余额刷新增加 per-provider 防重入保护
This commit is contained in:
fawney19
2026-03-08 02:29:51 +08:00
parent d0eca509d4
commit ef0f8dd4d0
6 changed files with 120 additions and 45 deletions

View File

@@ -152,6 +152,8 @@ ALLOWED_ACTIONS = {
"clear_cooldown",
"reset_cost",
"regenerate_fingerprint",
"clear_proxy",
"set_proxy",
}
_COOLDOWN_REASON_LABELS: dict[str, str] = {
@@ -988,6 +990,13 @@ class AdminBatchActionKeysAdapter(AdminApiAdapter):
),
)
if self.body.action == "set_proxy":
if not isinstance(self.body.payload, dict) or not self.body.payload:
raise HTTPException(
status_code=400,
detail="set_proxy action requires a non-empty payload with proxy config",
)
db = context.db
provider = db.query(Provider).filter(Provider.id == self.provider_id).first()
if not provider:
@@ -1028,11 +1037,26 @@ class AdminBatchActionKeysAdapter(AdminApiAdapter):
await pool_redis.clear_cost(pid, kid)
affected += 1
elif self.body.action == "clear_proxy":
key.proxy = None
affected += 1
elif self.body.action == "set_proxy":
key.proxy = self.body.payload
affected += 1
elif self.body.action == "regenerate_fingerprint":
key.fingerprint = generate_fingerprint(seed=None)
affected += 1
if self.body.action in {"enable", "disable", "delete", "regenerate_fingerprint"}:
if self.body.action in {
"enable",
"disable",
"delete",
"regenerate_fingerprint",
"clear_proxy",
"set_proxy",
}:
try:
db.commit()
except Exception as exc:
@@ -1040,6 +1064,18 @@ class AdminBatchActionKeysAdapter(AdminApiAdapter):
logger.error("batch action commit failed: {}", exc)
return BatchActionResponse(affected=0, message=f"commit failed: {exc}")
if self.body.action == "delete" and affected > 0:
from src.services.provider_keys.key_side_effects import run_delete_key_side_effects
try:
await run_delete_key_side_effects(
db=db,
provider_id=pid,
deleted_key_allowed_models=None,
)
except Exception as exc:
logger.error("batch delete side effects failed: {}", exc)
action_labels = {
"enable": "enabled",
"disable": "disabled",
@@ -1047,6 +1083,8 @@ class AdminBatchActionKeysAdapter(AdminApiAdapter):
"clear_cooldown": "cooldown cleared",
"reset_cost": "cost reset",
"regenerate_fingerprint": "fingerprint regenerated",
"clear_proxy": "proxy cleared",
"set_proxy": "proxy set",
}
admin_name = context.user.username if context.user else "admin"

View File

@@ -164,8 +164,9 @@ class BatchImportResponse(BaseModel):
class BatchActionRequest(BaseModel):
key_ids: list[str] = Field(..., max_length=500)
action: str # enable / disable / delete / clear_cooldown / reset_cost / regenerate_fingerprint
key_ids: list[str] = Field(..., max_length=2000)
action: str # enable / disable / delete / clear_cooldown / reset_cost / regenerate_fingerprint / clear_proxy / set_proxy
payload: dict[str, Any] | None = None
class BatchActionResponse(BaseModel):