feat: 添加密钥检查调度器并重构前端UI

主要变更:

- **调度器功能:**
    - 集成 APScheduler 实现定时任务,用于定期检查API密钥的有效性。
    - 在 `.env.example` 和 `app/config/config.py` 中添加了 `CHECK_INTERVAL_HOURS` 和 `TIMEZONE` 配置项。
    - 在应用生命周期 (`app/core/application.py`) 中添加了调度器的启动和停止逻辑。
    - 新增 `app/scheduler/` 目录及相关实现 (`key_checker.py`)。
    - 新增 `app/router/scheduler_routes.py` 用于调度器相关API (如果未来需要)。
    - 在 `requirements.txt` 中添加 `apscheduler` 依赖。

- **前端重构与改进:**
    - 引入 `app/templates/base.html` 作为基础模板,统一页面结构和样式引入。
    - 使用新的样式(推测为Tailwind CSS)重构了 `auth.html`, `config_editor.html`, `error_logs.html`, `keys_status.html` 页面,提升了UI一致性和响应式布局。
    - 删除了旧的CSS文件 (`auth.css`, `config_editor.css`, `error_logs.css`, `keys_status.css`)。
    - 更新了对应的 JavaScript 文件 (`config_editor.js`, `error_logs.js`, `keys_status.js`) 以适应新的HTML结构和交互。
    - 在 `keys_status.html` 页面增加了按失败次数过滤密钥、批量重置失败次数、确认模态框等功能。
    - 添加了新的 Logo 图片 (`logo.png`, `logo1.png`)。

- **其他:**
    - 更新了 `app/router/routes.py` 以包含新的路由。
    - 对 `app/service/key/key_manager.py` 和 `app/database/services.py` 进行了相关调整以支持新功能。
```
This commit is contained in:
snaily
2025-04-11 03:16:51 +08:00
parent 69261e98de
commit 51bb71bdb5
25 changed files with 2090 additions and 2776 deletions

View File

@@ -1,10 +1,9 @@
"""
数据库服务模块
"""
import datetime
import json
from typing import Dict, List, Optional, Any, Union
from datetime import date, timedelta # Import date and timedelta
from datetime import datetime
from sqlalchemy import select, insert, update, func # Import func for COUNT
@@ -142,7 +141,7 @@ async def add_error_log(
model_name=model_name,
error_code=error_code,
request_msg=request_msg_json,
request_time=datetime.datetime.now()
request_time=datetime.now()
)
)
await database.execute(query)
@@ -158,8 +157,8 @@ async def get_error_logs(
offset: int = 0,
key_search: Optional[str] = None,
error_search: Optional[str] = None,
start_date: Optional[date] = None,
end_date: Optional[date] = None
start_date: Optional[datetime] = None,
end_date: Optional[datetime] = None
) -> List[Dict[str, Any]]:
"""
获取错误日志,支持搜索和日期过滤
@@ -169,8 +168,8 @@ async def get_error_logs(
offset (int): 偏移量
key_search (Optional[str]): Gemini密钥搜索词 (模糊匹配)
error_search (Optional[str]): 错误类型或日志内容搜索词 (模糊匹配)
start_date (Optional[date]): 开始日期
end_date (Optional[date]): 结束日期
start_date (Optional[datetime]): 开始日期时间
end_date (Optional[datetime]): 结束日期时间
Returns:
List[Dict[str, Any]]: 错误日志列表
@@ -189,8 +188,8 @@ async def get_error_logs(
if start_date:
query = query.where(ErrorLog.request_time >= start_date)
if end_date:
# Add 1 day to end_date to include the whole day
query = query.where(ErrorLog.request_time < end_date + timedelta(days=1))
# Use the datetime object directly for comparison
query = query.where(ErrorLog.request_time < end_date)
# Apply ordering, limit, and offset
query = query.order_by(ErrorLog.request_time.desc()).limit(limit).offset(offset)
@@ -205,8 +204,8 @@ async def get_error_logs(
async def get_error_logs_count(
key_search: Optional[str] = None,
error_search: Optional[str] = None,
start_date: Optional[date] = None,
end_date: Optional[date] = None
start_date: Optional[datetime] = None,
end_date: Optional[datetime] = None
) -> int:
"""
获取符合条件的错误日志总数
@@ -214,8 +213,8 @@ async def get_error_logs_count(
Args:
key_search (Optional[str]): Gemini密钥搜索词 (模糊匹配)
error_search (Optional[str]): 错误类型或日志内容搜索词 (模糊匹配)
start_date (Optional[date]): 开始日期
end_date (Optional[date]): 结束日期
start_date (Optional[datetime]): 开始日期时间
end_date (Optional[datetime]): 结束日期时间
Returns:
int: 日志总数
@@ -234,7 +233,8 @@ async def get_error_logs_count(
if start_date:
query = query.where(ErrorLog.request_time >= start_date)
if end_date:
query = query.where(ErrorLog.request_time < end_date + timedelta(days=1))
# Use the datetime object directly for comparison
query = query.where(ErrorLog.request_time < end_date)
count_result = await database.fetch_one(query)
return count_result[0] if count_result else 0