diff --git a/api/config.py b/api/config.py index 110dd03..605cb20 100644 --- a/api/config.py +++ b/api/config.py @@ -61,6 +61,7 @@ CONFIG_KEYS = [ "cpa_cleanup_register_delay_seconds", "sub2api_api_url", "sub2api_api_key", + "sub2api_group_ids", "team_manager_url", "team_manager_key", "codex_proxy_url", diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index df1cf65..9c41d2c 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -203,6 +203,7 @@ const TAB_ITEMS = [ fields: [ { key: 'sub2api_api_url', label: 'API URL', placeholder: 'https://your-sub2api.example.com' }, { key: 'sub2api_api_key', label: 'API Key', secret: true }, + { key: 'sub2api_group_ids', label: '分组 ID', placeholder: '多个分组用英文逗号分隔,例如 2,4,8' }, ], }, { diff --git a/platforms/chatgpt/sub2api_upload.py b/platforms/chatgpt/sub2api_upload.py index 0ed880e..a1d80a6 100644 --- a/platforms/chatgpt/sub2api_upload.py +++ b/platforms/chatgpt/sub2api_upload.py @@ -29,6 +29,30 @@ def _get_config_value(key: str) -> str: return "" +def _parse_group_ids(raw: Any, fallback: list[int] | None = None) -> list[int]: + candidates: list[Any] + if isinstance(raw, str): + candidates = [part.strip() for part in raw.split(",")] + elif isinstance(raw, (list, tuple, set)): + candidates = list(raw) + elif raw is None: + candidates = [] + else: + candidates = [raw] + + values: list[int] = [] + for item in candidates: + text = str(item or "").strip() + if not text: + continue + try: + values.append(int(text)) + except ValueError: + continue + + return values or list(fallback or DEFAULT_GROUP_IDS) + + def _decode_jwt_payload(token: str) -> dict[str, Any]: try: parts = str(token or "").split(".") @@ -101,7 +125,7 @@ def _build_sub2api_account_payload(account, group_ids: list[int] | None = None) "id_token": id_token, }, "extra": {"email": email}, - "group_ids": group_ids or DEFAULT_GROUP_IDS, + "group_ids": _parse_group_ids(group_ids), "concurrency": 10, "priority": 1, "auto_pause_on_expired": True, @@ -117,13 +141,16 @@ def upload_to_sub2api( """上传单个账号到 Sub2API 管理后台。""" api_url = str(api_url or _get_config_value("sub2api_api_url")).strip() api_key = str(api_key or _get_config_value("sub2api_api_key")).strip() + resolved_group_ids = _parse_group_ids( + _get_config_value("sub2api_group_ids") if group_ids is None else group_ids + ) if not api_url: return False, "Sub2API API URL 未配置" if not api_key: return False, "Sub2API API Key 未配置" - payload = _build_sub2api_account_payload(account, group_ids=group_ids) + payload = _build_sub2api_account_payload(account, group_ids=resolved_group_ids) url = f"{api_url.rstrip('/')}/api/v1/admin/accounts" headers = { "Content-Type": "application/json",