yangtb24 commited on
Commit
2809c18
·
verified ·
1 Parent(s): 834bfcd

Upload 70 files

Browse files
config.py CHANGED
@@ -28,7 +28,11 @@ PLATFORMS = [
28
  {"id": "anthropic", "name": "Anthropic"},
29
  {"id": "openai", "name": "OpenAI"},
30
  {"id": "google", "name": "Google"},
31
- {"id": "deepseek", "name": "Deepseek"}
 
 
 
 
32
  ]
33
 
34
  # 平台标签样式
@@ -52,16 +56,40 @@ PLATFORM_STYLES = {
52
  "background-color": "rgba(77, 107, 254, 0.1)",
53
  "border-color": "rgba(77, 107, 254, 0.3)",
54
  "color": "#3246d3"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
  }
57
 
58
  # API调用节流控制配置
59
  PLATFORM_LIMITS = {
60
- 'openai': 50,
61
- 'anthropic': 50,
62
- 'google': 50,
63
- 'deepseek': 50,
64
- 'default': 10
 
 
 
 
65
  }
66
 
67
  # 请求节流时间窗口(秒)
 
28
  {"id": "anthropic", "name": "Anthropic"},
29
  {"id": "openai", "name": "OpenAI"},
30
  {"id": "google", "name": "Google"},
31
+ {"id": "deepseek", "name": "Deepseek"},
32
+ {"id": "siliconflow", "name": "SiliconFlow"},
33
+ {"id": "xai", "name": "xAI"},
34
+ {"id": "groq", "name": "Groq"},
35
+ {"id": "openrouter", "name": "OpenRouter"}
36
  ]
37
 
38
  # 平台标签样式
 
56
  "background-color": "rgba(77, 107, 254, 0.1)",
57
  "border-color": "rgba(77, 107, 254, 0.3)",
58
  "color": "#3246d3"
59
+ },
60
+ "siliconflow": {
61
+ "background-color": "rgba(124, 58, 237, 0.1)",
62
+ "border-color": "rgba(124, 58, 237, 0.3)",
63
+ "color": "#6429c8"
64
+ },
65
+ "xai": {
66
+ "background-color": "rgba(90, 90, 90, 0.1)",
67
+ "border-color": "rgba(90, 90, 90, 0.3)",
68
+ "color": "#5A5A5A"
69
+ },
70
+ "groq": {
71
+ "background-color": "rgba(255, 95, 31, 0.1)",
72
+ "border-color": "rgba(255, 95, 31, 0.3)",
73
+ "color": "#FF5F1F"
74
+ },
75
+ "openrouter": {
76
+ "background-color": "rgba(61, 88, 171, 0.1)",
77
+ "border-color": "rgba(61, 88, 171, 0.3)",
78
+ "color": "#3D58AB"
79
  }
80
  }
81
 
82
  # API调用节流控制配置
83
  PLATFORM_LIMITS = {
84
+ 'openai': 100,
85
+ 'anthropic': 100,
86
+ 'google': 500,
87
+ 'deepseek': 50,
88
+ 'siliconflow': 50,
89
+ 'xai': 50,
90
+ 'groq': 50,
91
+ 'openrouter': 50,
92
+ 'default': 50
93
  }
94
 
95
  # 请求节流时间窗口(秒)
core/__pycache__/update.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/update.cpython-313.pyc and b/core/__pycache__/update.cpython-313.pyc differ
 
core/api/__pycache__/xai.cpython-313.pyc ADDED
Binary file (2.18 kB). View file
 
core/api/xai.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ xAI API相关功能模块 - 提供xAI API的调用和验证功能
3
+ """
4
+ import requests
5
+
6
+ def validate_api_key(api_key):
7
+ """
8
+ 验证xAI API密钥是否有效
9
+
10
+ Args:
11
+ api_key (str): 需要验证的xAI API密钥
12
+
13
+ Returns:
14
+ dict: 包含验证结果的字典,包括:
15
+ - success (bool): API密钥验证成功为True,失败为False
16
+ - return_message (str): 验证响应的具体消息,成功时为"200: Success!",失败时为错误详情
17
+ - balance (float): 账户余额,固定为0
18
+ - states (str): 账户状态,xAI没有Tier等级,默认为空字符串
19
+ """
20
+ url = "https://api.x.ai/v1/chat/completions"
21
+
22
+ headers = {
23
+ "Authorization": f"Bearer {api_key}",
24
+ "Content-Type": "application/json"
25
+ }
26
+
27
+ payload = {
28
+ "model": "grok-2-1212",
29
+ "max_tokens": 1,
30
+ "messages": [
31
+ {"role": "user", "content": "Hello"}
32
+ ]
33
+ }
34
+
35
+ try:
36
+ response = requests.post(url, headers=headers, json=payload)
37
+
38
+ if response.status_code == 200:
39
+ return {
40
+ "success": True,
41
+ "return_message": "200: Success!",
42
+ "balance": 0,
43
+ "states": ""
44
+ }
45
+ else:
46
+ return_message = ""
47
+ try:
48
+ error_data = response.json()
49
+ if "error" in error_data:
50
+ return_message = error_data["error"].get("message", "")
51
+ return_message = f"{response.status_code}: {return_message}"
52
+ except:
53
+ return_message = f"{response.status_code}: {response.text or f'HTTP错误'}"
54
+
55
+ return {
56
+ "success": False,
57
+ "return_message": return_message,
58
+ "balance": 0,
59
+ "states": ""
60
+ }
61
+ except Exception as e:
62
+ error_str = str(e)
63
+ print(f"验证API密钥时出错: {error_str}")
64
+ return {
65
+ "success": False,
66
+ "return_message": f"500: 请求异常: {error_str}",
67
+ "balance": 0,
68
+ "states": ""
69
+ }
core/update.py CHANGED
@@ -4,6 +4,7 @@ API密钥更新模块 - 提供API密钥的验证和更新功能
4
  import json
5
  import os
6
  import sqlite3
 
7
  from datetime import datetime
8
  from core.api_manager import get_api_manager
9
  from utils.db import get_db_connection
@@ -60,8 +61,8 @@ def update(key_id):
60
  except Exception as e:
61
  return {"success": False, "message": f"验证API密钥时出错: {str(e)}"}
62
 
63
- # 当前时间
64
- current_time = datetime.now().isoformat()
65
 
66
  # 将布尔值转换为整数
67
  success_int = 1 if result.get("success", False) else 0
 
4
  import json
5
  import os
6
  import sqlite3
7
+ import pytz
8
  from datetime import datetime
9
  from core.api_manager import get_api_manager
10
  from utils.db import get_db_connection
 
61
  except Exception as e:
62
  return {"success": False, "message": f"验证API密钥时出错: {str(e)}"}
63
 
64
+ # 当前时间 - 使用亚洲/上海时区 (UTC+8)
65
+ current_time = datetime.now(pytz.timezone('Asia/Shanghai')).isoformat()
66
 
67
  # 将布尔值转换为整数
68
  success_int = 1 if result.get("success", False) else 0
models/__pycache__/api_key.cpython-313.pyc CHANGED
Binary files a/models/__pycache__/api_key.cpython-313.pyc and b/models/__pycache__/api_key.cpython-313.pyc differ
 
routes/__pycache__/api.cpython-313.pyc CHANGED
Binary files a/routes/__pycache__/api.cpython-313.pyc and b/routes/__pycache__/api.cpython-313.pyc differ
 
routes/__pycache__/web.cpython-313.pyc CHANGED
Binary files a/routes/__pycache__/web.cpython-313.pyc and b/routes/__pycache__/web.cpython-313.pyc differ
 
routes/web.py CHANGED
@@ -1,6 +1,7 @@
1
  """
2
  Web路由模块 - 处理所有页面请求和身份验证
3
  """
 
4
  from flask import Blueprint, render_template, request, redirect, url_for, make_response, session
5
  from datetime import datetime
6
  from config import ADMIN_PASSWORD, PLATFORMS, PLATFORM_STYLES, TOKEN_EXPIRY_DAYS
@@ -10,10 +11,50 @@ from models.api_key import ApiKeyManager
10
  # 创建Web蓝图
11
  web_bp = Blueprint('web', __name__)
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  @web_bp.route('/')
14
  def index():
15
  """首页 - 显示API密钥管理界面"""
16
  api_keys_data = ApiKeyManager.get_all_keys()
 
 
 
 
 
 
17
 
18
  # 按平台分组密钥
19
  grouped_keys = {}
@@ -24,7 +65,7 @@ def index():
24
  }
25
 
26
  # 将密钥加入对应的平台组
27
- for key in api_keys_data.get("api_keys", []):
28
  platform_id = key.get("platform", "other").lower()
29
  if platform_id not in grouped_keys:
30
  platform_id = "other"
 
1
  """
2
  Web路由模块 - 处理所有页面请求和身份验证
3
  """
4
+ import re # 导入正则表达式模块
5
  from flask import Blueprint, render_template, request, redirect, url_for, make_response, session
6
  from datetime import datetime
7
  from config import ADMIN_PASSWORD, PLATFORMS, PLATFORM_STYLES, TOKEN_EXPIRY_DAYS
 
11
  # 创建Web蓝图
12
  web_bp = Blueprint('web', __name__)
13
 
14
+ # 辅助函数:为API密钥生成排序键
15
+ def get_sort_key(key):
16
+ """
17
+ 生成用于排序的元组 (balance, platform_priority)。
18
+ - balance: 主要排序键,降序。
19
+ - platform_priority: 次要排序键,仅在 balance 相同时生效,降序。
20
+ - Google: paid=1, free=0
21
+ - OpenAI/Claude: t5=5, t4=4, ..., t1=1, 其他=0
22
+ """
23
+ balance = key.get('balance', 0)
24
+ platform_priority = 0
25
+ platform = key.get('platform', '').lower()
26
+ name = key.get('name', '').lower() # 用于 OpenAI/Claude tier 判断
27
+ states = key.get('states', '').lower() # 获取 states 字段并转小写,用于 Google 判断
28
+
29
+ if platform == 'google':
30
+ if 'paid' in states: # 检查 states 字段是否包含 'paid' (已转小写)
31
+ platform_priority = 1 # paid 优先
32
+ elif platform in ['openai', 'anthropic']: # 假设 Claude 的 platform id 是 'anthropic'
33
+ match = re.search(r't(\d)', name)
34
+ if match:
35
+ try:
36
+ tier = int(match.group(1))
37
+ if 1 <= tier <= 5: # 假设 tier 在 1-5 之间
38
+ platform_priority = tier
39
+ except ValueError:
40
+ pass # 如果转换失败,保持 priority 为 0
41
+
42
+ # 返回元组,Python 的 sorted 会按元组顺序比较
43
+ # 因为 sorted 默认升序,我们需要对 balance 和 priority 都取反来实现降序效果
44
+ # 或者直接在 sorted 中用 reverse=True,然后只对 platform_priority 取反(或用正数表示优先级)
45
+ # 这里我们用 reverse=True,所以 balance 自然降序,platform_priority 越大越优先
46
+ return (balance, platform_priority)
47
+
48
  @web_bp.route('/')
49
  def index():
50
  """首页 - 显示API密钥管理界面"""
51
  api_keys_data = ApiKeyManager.get_all_keys()
52
+ all_keys_list = api_keys_data.get("api_keys", [])
53
+
54
+ # 按 balance 降序排序密钥
55
+ # 注意:确保 balance 存在且为数字类型,否则排序可能出错。使用 .get('balance', 0) 提供默认值。
56
+ # 使用新的排序逻辑
57
+ sorted_keys = sorted(all_keys_list, key=get_sort_key, reverse=True)
58
 
59
  # 按平台分组密钥
60
  grouped_keys = {}
 
65
  }
66
 
67
  # 将密钥加入对应的平台组
68
+ for key in sorted_keys: # 使用排序后的列表进行分组
69
  platform_id = key.get("platform", "other").lower()
70
  if platform_id not in grouped_keys:
71
  platform_id = "other"
static/img/groq.svg ADDED
static/img/openrouter.svg ADDED
static/img/siliconflow.svg ADDED
static/img/xai.svg ADDED
static/js/api-key-manager/core.js CHANGED
@@ -10,19 +10,21 @@ function initApiKeyManager() {
10
  // 初始化平台ID列表
11
  this.platformIds = platforms.map(platform => platform.id);
12
 
13
- // 从localStorage读取平台展开状态,如果有的话
14
- const savedPlatformStates = localStorage.getItem('platformStates');
 
 
 
 
 
 
 
15
  const parsedPlatformStates = savedPlatformStates ? JSON.parse(savedPlatformStates) : {};
16
 
17
  // 从localStorage读取平台筛选状态,如果有的话
18
  const savedPlatformFilters = localStorage.getItem('platformFilters');
19
  const parsedPlatformFilters = savedPlatformFilters ? JSON.parse(savedPlatformFilters) : {};
20
 
21
- // 从localStorage读取当前视图状态,如果有的话
22
- const savedView = localStorage.getItem('keyView');
23
- if (savedView === 'valid' || savedView === 'invalid') {
24
- this.currentView = savedView;
25
- }
26
 
27
  // 初始化平台状态,优先使用保存的状态
28
  platforms.forEach(platform => {
 
10
  // 初始化平台ID列表
11
  this.platformIds = platforms.map(platform => platform.id);
12
 
13
+ // 从localStorage读取当前视图状态,如果有的话
14
+ const savedView = localStorage.getItem('keyView');
15
+ if (savedView === 'valid' || savedView === 'invalid') {
16
+ this.currentView = savedView;
17
+ }
18
+
19
+ // 从localStorage读取对应视图的平台展开状态,如果有的话
20
+ const stateKey = `platformStates_${this.currentView}`;
21
+ const savedPlatformStates = localStorage.getItem(stateKey);
22
  const parsedPlatformStates = savedPlatformStates ? JSON.parse(savedPlatformStates) : {};
23
 
24
  // 从localStorage读取平台筛选状态,如果有的话
25
  const savedPlatformFilters = localStorage.getItem('platformFilters');
26
  const parsedPlatformFilters = savedPlatformFilters ? JSON.parse(savedPlatformFilters) : {};
27
 
 
 
 
 
 
28
 
29
  // 初始化平台状态,优先使用保存的状态
30
  platforms.forEach(platform => {
static/js/api-key-manager/main-manager.js CHANGED
@@ -140,10 +140,29 @@ function apiKeyManager() {
140
  // 切换当前视图(有效/无效密钥)
141
  switchView(view) {
142
  if (this.currentView !== view) {
 
 
 
 
 
143
  this.currentView = view;
144
- // 保存用户的选择到localStorage
 
145
  localStorage.setItem('keyView', view);
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  // 重置选择状态
148
  this.selectedKeys = [];
149
  this.selectedPlatforms = [];
 
140
  // 切换当前视图(有效/无效密钥)
141
  switchView(view) {
142
  if (this.currentView !== view) {
143
+ // 保存当前视图的平台展开状态
144
+ const currentStateKey = `platformStates_${this.currentView}`;
145
+ localStorage.setItem(currentStateKey, JSON.stringify(this.platformStates));
146
+
147
+ // 切换视图
148
  this.currentView = view;
149
+
150
+ // 保存用户的视图选择到localStorage
151
  localStorage.setItem('keyView', view);
152
 
153
+ // 加载新视图的平台展开状态
154
+ const newStateKey = `platformStates_${view}`;
155
+ const savedPlatformStates = localStorage.getItem(newStateKey);
156
+ if (savedPlatformStates) {
157
+ this.platformStates = JSON.parse(savedPlatformStates);
158
+ } else {
159
+ // 如果没有保存过这个视图的状态,使用默认值(全部展开)
160
+ const platforms = this.getPlatforms();
161
+ platforms.forEach(platform => {
162
+ this.platformStates[platform.id] = true;
163
+ });
164
+ }
165
+
166
  // 重置选择状态
167
  this.selectedKeys = [];
168
  this.selectedPlatforms = [];
static/js/api-key-manager/platform-utils.js CHANGED
@@ -7,8 +7,9 @@
7
  function togglePlatform(platformId) {
8
  this.platformStates[platformId] = !this.platformStates[platformId];
9
 
10
- // 保存展开状态到localStorage
11
- localStorage.setItem('platformStates', JSON.stringify(this.platformStates));
 
12
  }
13
 
14
  // 获取平台API密钥数量
 
7
  function togglePlatform(platformId) {
8
  this.platformStates[platformId] = !this.platformStates[platformId];
9
 
10
+ // 保存展开状态到localStorage - 分开存储不同视图的状态
11
+ const stateKey = `platformStates_${this.currentView}`;
12
+ localStorage.setItem(stateKey, JSON.stringify(this.platformStates));
13
  }
14
 
15
  // 获取平台API密钥数量
utils/__pycache__/db.cpython-313.pyc CHANGED
Binary files a/utils/__pycache__/db.cpython-313.pyc and b/utils/__pycache__/db.cpython-313.pyc differ