mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-09-05 23:56:37 +08:00
feat(错误日志): 添加排序和删除功能
为错误日志页面增加了按 ID 排序以及单条和批量删除日志的功能。
主要变更:
后端 (Python/FastAPI):
- `services.py`:
- `get_error_logs`: 添加 `sort_by` 和 `sort_order` 参数以支持排序。
- 新增 `delete_error_logs`: 实现基于 ID 列表的批量删除。
- 新增 `delete_error_log_by_id`: 实现基于单个 ID 的删除。
- `error_log_routes.py`:
- `GET /api/logs/errors`: 添加 `sortBy` 和 `sortOrder` 查询参数以支持前端排序请求。
- 新增 `DELETE /api/logs/errors`: 处理批量删除请求。
- 新增 `DELETE /api/logs/errors/{log_id}`: 处理单条删除请求。
- `connection.py`: 移除了不再使用的同步 SQLAlchemy Session 相关代码。
前端 (HTML/JavaScript):
- `error_logs.html`:
- 调整了搜索/操作区域布局,添加了批量删除按钮。
- ID 表头增加排序图标和点击事件。
- 表格行操作列添加了删除按钮。
- 新增了删除确认模态框。
- `error_logs.js`:
- 添加了处理 ID 排序点击的逻辑,更新排序状态并重新加载数据。
- 添加了处理单条和批量删除按钮点击的逻辑。
- 实现了删除确认模态框的显示/隐藏及确认逻辑。
- 修改 `loadErrorLogs` 以包含排序参数。
- 修改 `renderErrorLogs` 以添加行删除按钮和必要的 `data-log-id` 属性。
- 更新了全选/取消全选逻辑以同步批量删除按钮状态。
This commit is contained in:
@@ -49,27 +49,24 @@
|
||||
}
|
||||
/* Modal styles are in base.html */
|
||||
|
||||
/* 自定义样式调整:减小搜索按钮和复制按钮的高度和宽度 */
|
||||
#searchBtn, #copySelectedKeysBtn {
|
||||
padding-top: 0.4rem !important;
|
||||
padding-bottom: 0.4rem !important;
|
||||
width: 96px !important;
|
||||
}
|
||||
|
||||
/* 增加搜索按钮和时间控件之间的间距 */
|
||||
.search-controls-grid {
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* 确保输入框和按钮高度一致 */
|
||||
.search-controls-grid input, .date-range-container input {
|
||||
padding-top: 0.4rem !important;
|
||||
padding-bottom: 0.4rem !important;
|
||||
input[type="text"], input[type="datetime-local"], select, button {
|
||||
height: 36px !important;
|
||||
}
|
||||
|
||||
/* 为搜索按钮添加额外的左边距 */
|
||||
#searchBtn {
|
||||
margin-left: 1rem !important;
|
||||
/* 日期选择器样式优化 */
|
||||
.date-range-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* 确保所有输入框在小屏幕上正确显示 */
|
||||
@media (max-width: 640px) {
|
||||
input[type="datetime-local"] {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
@@ -107,21 +104,34 @@
|
||||
<!-- Removed the original controls div -->
|
||||
|
||||
<!-- 搜索与操作控件 -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-6 gap-3 mb-6">
|
||||
<input type="text" id="keySearch" placeholder="搜索密钥 (部分)" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 col-span-1">
|
||||
<input type="text" id="errorSearch" placeholder="搜索错误类型/日志" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 col-span-1">
|
||||
<input type="text" id="errorCodeSearch" placeholder="搜索错误码" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 col-span-1">
|
||||
<div class="flex items-center gap-2 col-span-1 lg:col-span-2">
|
||||
<input type="datetime-local" id="startDate" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 text-sm">
|
||||
<span class="text-gray-700">至</span>
|
||||
<input type="datetime-local" id="endDate" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 text-sm">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-[1fr_auto] items-center gap-4 mb-6"> <!-- 修改为items-center -->
|
||||
<!-- Left side: Search inputs and date range -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 w-full"> <!-- 修改为3列布局 -->
|
||||
<input type="text" id="keySearch" placeholder="搜索密钥 (部分)" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50">
|
||||
<input type="text" id="errorSearch" placeholder="搜索错误类型/日志" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50">
|
||||
<input type="text" id="errorCodeSearch" placeholder="搜索错误码" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50">
|
||||
<!-- 日期选择器单独一行 -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2 col-span-1 sm:col-span-2 lg:col-span-3 mt-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<label class="text-sm text-gray-700 whitespace-nowrap">开始时间:</label>
|
||||
<input type="datetime-local" id="startDate" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 text-sm w-full">
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<label class="text-sm text-gray-700 whitespace-nowrap">结束时间:</label>
|
||||
<input type="datetime-local" id="endDate" style="height: 36px;" class="px-3 py-1 rounded-lg border border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 text-sm w-full">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 col-span-1">
|
||||
<button id="searchBtn" style="height: 36px; width: 80px;" class="flex items-center justify-center bg-primary-600 hover:bg-primary-700 text-white rounded-lg font-medium transition-all duration-200">
|
||||
<i class="fas fa-search mr-1"></i>搜索
|
||||
<!-- Right side: Action buttons -->
|
||||
<div class="flex items-center gap-3 flex-shrink-0"> <!-- 移除上边距 -->
|
||||
<button id="searchBtn" class="flex items-center justify-center px-4 py-1.5 bg-primary-600 hover:bg-primary-700 text-white rounded-lg font-medium transition-all duration-200 shadow-sm hover:shadow-md whitespace-nowrap" style="height: 36px;">
|
||||
<i class="fas fa-search mr-1.5"></i>搜索
|
||||
</button>
|
||||
<button id="copySelectedKeysBtn" style="height: 36px; width: 80px;" class="flex items-center justify-center bg-success-600 hover:bg-success-700 text-white rounded-lg font-medium transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
|
||||
<i class="far fa-copy mr-1"></i>复制
|
||||
<button id="copySelectedKeysBtn" class="flex items-center justify-center px-4 py-1.5 bg-success-600 hover:bg-success-700 text-white rounded-lg font-medium transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed shadow-sm hover:shadow-md whitespace-nowrap" style="height: 36px;" disabled>
|
||||
<i class="far fa-copy mr-1.5"></i>复制
|
||||
</button>
|
||||
<button id="deleteSelectedBtn" class="flex items-center justify-center px-4 py-1.5 bg-danger-600 hover:bg-danger-700 text-white rounded-lg font-medium transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed shadow-sm hover:shadow-md whitespace-nowrap" style="height: 36px;" disabled>
|
||||
<i class="fas fa-trash-alt mr-1.5"></i>删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,13 +144,15 @@
|
||||
<th class="px-3 py-3 font-semibold rounded-tl-lg w-12 text-center"> <!-- Adjusted padding and width -->
|
||||
<input type="checkbox" id="selectAllCheckbox" class="form-checkbox h-4 w-4 text-primary-600 border-gray-300 rounded focus:ring-primary-500">
|
||||
</th>
|
||||
<th class="px-5 py-3 font-semibold">ID</th> <!-- Increased padding, adjusted rounding -->
|
||||
<th class="px-5 py-3 font-semibold cursor-pointer" id="sortById">
|
||||
ID <i class="fas fa-sort ml-1 text-gray-400"></i>
|
||||
</th>
|
||||
<th class="px-5 py-3 font-semibold">Gemini密钥</th>
|
||||
<th class="px-5 py-3 font-semibold">错误类型</th>
|
||||
<th class="px-5 py-3 font-semibold">错误码</th>
|
||||
<th class="px-5 py-3 font-semibold">模型名称</th>
|
||||
<th class="px-5 py-3 font-semibold">请求时间</th>
|
||||
<th class="px-5 py-3 font-semibold rounded-tr-lg">操作</th> <!-- Adjusted rounding -->
|
||||
<th class="px-5 py-3 font-semibold rounded-tr-lg text-center">操作</th> <!-- Adjusted rounding and centered -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="errorLogsTable" class="divide-y divide-gray-200">
|
||||
@@ -274,6 +286,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 删除确认模态框 -->
|
||||
<div id="deleteConfirmModal" class="modal">
|
||||
<div class="w-full max-w-md mx-auto bg-white rounded-xl shadow-xl overflow-hidden animate-fade-in">
|
||||
<div class="p-6">
|
||||
<div class="flex justify-between items-center border-b border-gray-200 pb-3 mb-4">
|
||||
<h2 class="text-lg font-semibold text-gray-800">确认删除</h2>
|
||||
<button id="closeDeleteConfirmModalBtn" class="text-gray-400 hover:text-gray-600 text-xl">×</button>
|
||||
</div>
|
||||
<p id="deleteConfirmMessage" class="text-gray-700 mb-6">你确定要删除选中的项目吗?此操作不可恢复!</p>
|
||||
<div class="flex justify-end gap-3">
|
||||
<button id="cancelDeleteBtn" type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-5 py-2 rounded-lg font-medium transition">取消</button>
|
||||
<button id="confirmDeleteBtn" type="button" class="bg-danger-600 hover:bg-danger-700 text-white px-5 py-2 rounded-lg font-medium transition">确认删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block body_scripts %}
|
||||
|
||||
Reference in New Issue
Block a user