mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-05-12 02:19:59 +08:00
本次提交主要包含以下更新:
- **错误日志页面增强**:
- 重构了 [`app/static/js/error_logs.js`](app/static/js/error_logs.js) 中的分页逻辑,将样式控制移至 CSS,简化了 JavaScript 代码。
- 更新了 [`app/templates/error_logs.html`](app/templates/error_logs.html) 中的分页样式,使其与 `keys_status.html` 保持一致,提升了视觉统一性。
- 在错误日志页面新增了“清空全部”按钮,方便用户一键清除所有错误记录。
- 调整了错误日志表格头部的文本颜色为白色,以改善深色主题下的可读性。
- **应用初始化与配置优化**:
- 调整了 [`app/config/config.py`](app/config/config.py) 中日志记录器的获取方式,确保在配置加载早期即可用。
- 在 [`app/core/application.py`](app/core/application.py) 中引入了更明确的数据库连接管理(连接、断开、初始化)逻辑。
- 优化了 [`app/utils/helpers.py`](app/utils/helpers.py) 中项目路径和版本文件路径的定义方式,使其在模块级别初始化。
- **依赖清理**:
- 从 [`requirements.txt`](requirements.txt) 中移除了不必要的注释。
这些更改旨在提升错误日志模块的用户体验和功能性,并优化应用程序的启动和配置管理流程。
677 lines
23 KiB
HTML
677 lines
23 KiB
HTML
{% extends "base.html" %} {% block title %}错误日志管理 - Gemini Balance{%
|
|
endblock %} {% block head_extra_styles %}
|
|
<style>
|
|
/* error_logs.html specific styles */
|
|
.styled-table th {
|
|
position: sticky;
|
|
top: 0;
|
|
background-color: rgba(80, 60, 160, 0.8); /* theming: table header bg */
|
|
color: #ffffff !important; /* theming: table header text, ensured light */
|
|
z-index: 10;
|
|
border-bottom: 1px solid rgba(120, 100, 200, 0.4);
|
|
}
|
|
.styled-table tbody tr:hover {
|
|
background-color: rgba(90, 70, 170, 0.4); /* theming: table row hover */
|
|
}
|
|
.styled-table td {
|
|
padding: 12px 20px;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
max-width: 250px;
|
|
color: #d1d5db; /* theming: table cell text (gray-300) */
|
|
border-bottom: 1px solid rgba(120, 100, 200, 0.2); /* theming: cell border */
|
|
}
|
|
.styled-table td:nth-child(4) {
|
|
white-space: nowrap;
|
|
}
|
|
.btn-view-details {
|
|
background-color: rgba(107, 70, 193, 0.4); /* theming */
|
|
color: #c4b5fd; /* theming */
|
|
padding: 6px 12px;
|
|
border-radius: 6px;
|
|
font-weight: 500;
|
|
transition: all 0.2s ease-in-out;
|
|
border: 1px solid rgba(120, 100, 200, 0.6); /* theming */
|
|
}
|
|
.btn-view-details:hover {
|
|
background-color: rgba(120, 100, 200, 0.6); /* theming */
|
|
color: #ede9fe; /* theming */
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
}
|
|
@media (max-width: 768px) {
|
|
.search-container {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
input[type="text"],
|
|
input[type="datetime-local"],
|
|
select,
|
|
button {
|
|
height: 36px !important;
|
|
}
|
|
.form-input-themed,
|
|
input[type="datetime-local"],
|
|
select#pageSize {
|
|
background-color: rgba(255, 255, 255, 0.1) !important;
|
|
border-color: rgba(120, 100, 200, 0.5) !important;
|
|
color: #ffffff !important;
|
|
}
|
|
.form-input-themed::placeholder,
|
|
input[type="datetime-local"]::placeholder {
|
|
color: #a0aec0 !important;
|
|
}
|
|
.form-input-themed:focus,
|
|
input[type="datetime-local"]:focus,
|
|
select#pageSize:focus {
|
|
border-color: #a78bfa !important;
|
|
box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.4) !important;
|
|
}
|
|
select#pageSize {
|
|
/* Styles from config_editor.html .form-select-themed, adapted for select#pageSize */
|
|
background-color: rgba(60, 40, 130, 0.6) !important;
|
|
border: 1px solid rgba(167, 139, 250, 0.7) !important;
|
|
color: #ffffff !important;
|
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%23d8b4fe' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 8l4 4 4-4'/%3e%3c/svg%3e") !important;
|
|
appearance: none !important;
|
|
padding: 0.6rem 2.5rem 0.6rem 0.8rem !important;
|
|
background-repeat: no-repeat !important;
|
|
background-position: right 0.6rem center !important;
|
|
background-size: 1.5em 1.5em !important;
|
|
border-radius: 0.5rem !important;
|
|
font-weight: 500 !important;
|
|
height: 36px !important; /* Retain original height or use auto */
|
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) !important;
|
|
cursor: pointer !important;
|
|
}
|
|
|
|
select#pageSize:focus {
|
|
border-color: #d8b4fe !important; /* violet-300 */
|
|
box-shadow: 0 0 0 3px rgba(216, 180, 254, 0.4) !important; /* ring-violet-300 */
|
|
outline: none !important;
|
|
}
|
|
|
|
select#pageSize option {
|
|
background-color: rgba(76, 29, 149, 0.95) !important; /* 暗紫色背景 */
|
|
color: #ffffff !important;
|
|
padding: 8px !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%;
|
|
}
|
|
}
|
|
label {
|
|
color: #e2e8f0 !important; /* Light gray/white for labels */
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* 导航链接悬停样式 (从 config_editor.html 复制) */
|
|
.nav-link {
|
|
transition: all 0.2s ease-in-out;
|
|
}
|
|
|
|
.nav-link:hover {
|
|
background-color: rgba(120, 100, 200, 0.6) !important;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
/* Ensure text around pageSize select is light */
|
|
.pagination-text {
|
|
color: #e2e8f0 !important; /* Light gray/white for text */
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* New Pagination Styles (inspired by keys_status.html) */
|
|
ul.pagination a {
|
|
/* Targets the <a> tags directly within ul.pagination */
|
|
display: inline-flex; /* Consistent with flex from addPaginationLink */
|
|
align-items: center;
|
|
justify-content: center;
|
|
/* Tailwind classes from JS will handle padding, border-radius, font-size, transition */
|
|
/* Defaults for non-active, non-disabled, non-hover buttons */
|
|
background-color: rgba(80, 60, 160, 0.8);
|
|
color: #ffffff;
|
|
border: 1px solid rgba(120, 100, 200, 0.4);
|
|
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
|
min-width: 36px; /* Retain from original error_logs for consistency */
|
|
text-align: center; /* Retain from original error_logs for consistency */
|
|
/* Ensure base transition if not fully handled by JS's Tailwind classes */
|
|
transition: background-color 0.15s ease-in-out,
|
|
border-color 0.15s ease-in-out, color 0.15s ease-in-out;
|
|
}
|
|
|
|
ul.pagination a:hover:not(.active):not(.disabled) {
|
|
/* Hover for non-active, non-disabled */
|
|
background-color: rgba(
|
|
100,
|
|
80,
|
|
180,
|
|
0.9
|
|
); /* Slightly lighter/more interactive purple */
|
|
border-color: rgba(140, 120, 220, 0.7);
|
|
color: #ffffff;
|
|
}
|
|
|
|
ul.pagination a.active {
|
|
/* Active state */
|
|
background-color: rgba(120, 100, 200, 0.9);
|
|
border-color: rgba(150, 130, 230, 0.7);
|
|
color: #ffffff; /* Ensure text is white */
|
|
font-weight: 600; /* Make active page number bolder */
|
|
cursor: default;
|
|
}
|
|
|
|
ul.pagination a.disabled {
|
|
/* Disabled state for '...' or prev/next unavailable */
|
|
background-color: rgba(
|
|
80,
|
|
60,
|
|
160,
|
|
0.3
|
|
) !important; /* Use existing disabled bg */
|
|
color: rgba(
|
|
226,
|
|
232,
|
|
240,
|
|
0.6
|
|
) !important; /* Use existing disabled text color */
|
|
border-color: rgba(
|
|
120,
|
|
100,
|
|
200,
|
|
0.4
|
|
) !important; /* Use existing disabled border color */
|
|
cursor: not-allowed;
|
|
pointer-events: none;
|
|
text-shadow: none;
|
|
}
|
|
</style>
|
|
{% endblock %} {% block content %}
|
|
<div class="container mx-auto px-4">
|
|
<div
|
|
class="rounded-2xl shadow-xl p-6 md:p-8"
|
|
style="
|
|
background-color: rgba(80, 60, 160, 0.3);
|
|
backdrop-filter: blur(10px);
|
|
-webkit-backdrop-filter: blur(10px);
|
|
border: 1px solid rgba(150, 130, 230, 0.3);
|
|
"
|
|
>
|
|
<h1
|
|
class="text-3xl font-extrabold text-center text-transparent bg-clip-text bg-gradient-to-r from-violet-400 to-pink-400 mb-4"
|
|
>
|
|
<img
|
|
src="/static/icons/logo.png"
|
|
alt="Gemini Balance Logo"
|
|
class="h-9 inline-block align-middle mr-2"
|
|
/>
|
|
Gemini Balance - 错误日志
|
|
</h1>
|
|
|
|
<!-- Navigation Tabs -->
|
|
<div class="flex justify-center mb-8 overflow-x-auto pb-2 gap-2">
|
|
<a
|
|
href="/config"
|
|
class="nav-link whitespace-nowrap flex items-center justify-center gap-2 px-6 py-3 font-medium rounded-lg text-gray-200 hover:text-white transition-all duration-200"
|
|
style="background-color: rgba(107, 70, 193, 0.4)"
|
|
>
|
|
<i class="fas fa-cog"></i> 配置编辑
|
|
</a>
|
|
<a
|
|
href="/keys"
|
|
class="nav-link whitespace-nowrap flex items-center justify-center gap-2 px-6 py-3 font-medium rounded-lg text-gray-200 hover:text-white transition-all duration-200"
|
|
style="background-color: rgba(107, 70, 193, 0.4)"
|
|
>
|
|
<i class="fas fa-tachometer-alt"></i> 监控面板
|
|
</a>
|
|
<a
|
|
href="/logs"
|
|
class="whitespace-nowrap flex items-center justify-center gap-2 px-6 py-3 font-medium rounded-lg bg-violet-600 text-white shadow-md"
|
|
>
|
|
<i class="fas fa-exclamation-triangle"></i> 错误日志
|
|
</a>
|
|
</div>
|
|
|
|
<!-- 主内容区域 -->
|
|
<div
|
|
class="rounded-xl p-6 shadow-lg animate-fade-in"
|
|
style="
|
|
background-color: rgba(70, 50, 150, 0.5);
|
|
backdrop-filter: blur(5px);
|
|
-webkit-backdrop-filter: blur(5px);
|
|
border: 1px solid rgba(120, 100, 200, 0.2);
|
|
"
|
|
>
|
|
<h2
|
|
class="text-xl font-bold mb-6 pb-3 border-b flex items-center gap-2 text-gray-100 border-violet-300 border-opacity-30"
|
|
>
|
|
<i class="fas fa-bug text-violet-400"></i> 错误日志列表
|
|
</h2>
|
|
|
|
<!-- 搜索与操作控件 -->
|
|
<div
|
|
class="grid grid-cols-1 lg:grid-cols-[1fr_auto] items-center gap-4 mb-6"
|
|
>
|
|
<div
|
|
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 w-full"
|
|
>
|
|
<input
|
|
type="text"
|
|
id="keySearch"
|
|
placeholder="搜索密钥 (部分)"
|
|
class="px-3 py-1 rounded-lg border form-input-themed"
|
|
/>
|
|
<input
|
|
type="text"
|
|
id="errorSearch"
|
|
placeholder="搜索错误类型/日志"
|
|
class="px-3 py-1 rounded-lg border form-input-themed"
|
|
/>
|
|
<input
|
|
type="text"
|
|
id="errorCodeSearch"
|
|
placeholder="搜索错误码"
|
|
class="px-3 py-1 rounded-lg border form-input-themed"
|
|
/>
|
|
<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-300 whitespace-nowrap"
|
|
>开始时间:</label
|
|
>
|
|
<input
|
|
type="datetime-local"
|
|
id="startDate"
|
|
class="px-3 py-1 rounded-lg border text-sm w-full"
|
|
/>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<label class="text-sm text-gray-300 whitespace-nowrap"
|
|
>结束时间:</label
|
|
>
|
|
<input
|
|
type="datetime-local"
|
|
id="endDate"
|
|
class="px-3 py-1 rounded-lg border text-sm w-full"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<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-violet-600 hover:bg-violet-700 text-white rounded-lg font-medium transition-all duration-200 shadow-sm hover:shadow-md whitespace-nowrap"
|
|
>
|
|
<i class="fas fa-search mr-1.5"></i>搜索
|
|
</button>
|
|
<button
|
|
id="copySelectedKeysBtn"
|
|
class="flex items-center justify-center px-4 py-1.5 bg-sky-600 hover:bg-sky-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"
|
|
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-red-600 hover:bg-red-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"
|
|
disabled
|
|
>
|
|
<i class="fas fa-trash-alt mr-1.5"></i>删除
|
|
</button>
|
|
<button
|
|
id="deleteAllLogsBtn"
|
|
class="flex items-center justify-center px-4 py-1.5 bg-red-700 hover:bg-red-800 text-white rounded-lg font-medium transition-all duration-200 shadow-sm hover:shadow-md whitespace-nowrap"
|
|
title="清空所有错误日志"
|
|
>
|
|
<i class="fas fa-dumpster-fire mr-1.5"></i>清空全部
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 表格容器 -->
|
|
<div
|
|
class="overflow-x-auto rounded-lg border mb-6"
|
|
style="border-color: rgba(120, 100, 200, 0.3)"
|
|
>
|
|
<table class="styled-table w-full min-w-full text-sm">
|
|
<thead>
|
|
<tr class="text-left">
|
|
<th
|
|
class="px-3 py-3 font-semibold rounded-tl-lg w-12 text-center"
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
id="selectAllCheckbox"
|
|
class="form-checkbox h-4 w-4 text-violet-500 border-gray-500 rounded focus:ring-violet-500 bg-transparent"
|
|
/>
|
|
</th>
|
|
<th
|
|
class="px-5 py-3 font-semibold text-white cursor-pointer"
|
|
id="sortById"
|
|
>
|
|
ID <i class="fas fa-sort ml-1"></i>
|
|
</th>
|
|
<th class="px-5 py-3 font-semibold text-white">Gemini密钥</th>
|
|
<th class="px-5 py-3 font-semibold text-white">错误类型</th>
|
|
<th class="px-5 py-3 font-semibold text-white">错误码</th>
|
|
<th class="px-5 py-3 font-semibold text-white">模型名称</th>
|
|
<th class="px-5 py-3 font-semibold text-white">请求时间</th>
|
|
<th
|
|
class="px-5 py-3 font-semibold text-white rounded-tr-lg text-center"
|
|
>
|
|
操作
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody
|
|
id="errorLogsTable"
|
|
class="divide-y"
|
|
style="border-color: rgba(120, 100, 200, 0.2)"
|
|
>
|
|
<!-- 错误日志数据将通过JavaScript动态加载 -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- 状态指示器 -->
|
|
<div
|
|
id="loadingIndicator"
|
|
class="flex items-center justify-center p-8 hidden"
|
|
>
|
|
<div
|
|
class="animate-spin rounded-full h-12 w-12 border-b-2 border-violet-400"
|
|
></div>
|
|
<p class="ml-4 text-lg text-gray-300 font-medium">加载中,请稍候...</p>
|
|
</div>
|
|
|
|
<div id="noDataMessage" class="text-center py-12 text-gray-400 hidden">
|
|
<i class="fas fa-inbox text-5xl mb-3"></i>
|
|
<p class="text-lg">暂无错误日志数据</p>
|
|
</div>
|
|
|
|
<div
|
|
id="errorMessage"
|
|
class="p-4 rounded-lg font-medium text-center hidden"
|
|
style="background-color: rgba(220, 38, 38, 0.2); color: #fca5a5"
|
|
>
|
|
<i class="fas fa-exclamation-circle mr-2"></i>
|
|
加载错误日志失败,请稍后重试。
|
|
</div>
|
|
|
|
<!-- 分页与每页显示控件 -->
|
|
<div
|
|
class="flex flex-col sm:flex-row justify-between items-center mt-6 gap-4"
|
|
>
|
|
<div class="flex items-center gap-2 text-sm text-gray-300">
|
|
<label for="pageSize" class="font-medium pagination-text"
|
|
>每页显示:</label
|
|
>
|
|
<select
|
|
id="pageSize"
|
|
class="rounded-md border focus:ring focus:border-violet-400 px-2 py-1 text-sm"
|
|
>
|
|
<option value="10">10</option>
|
|
<option value="20" selected>20</option>
|
|
<option value="50">50</option>
|
|
<option value="100">100</option>
|
|
</select>
|
|
<span class="pagination-text">条</span>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<ul class="pagination flex items-center gap-1" id="pagination">
|
|
<!-- 分页控件将通过JavaScript动态加载 -->
|
|
</ul>
|
|
<div class="flex items-center gap-1">
|
|
<input
|
|
type="number"
|
|
id="pageInput"
|
|
min="1"
|
|
class="w-16 px-2 py-1 rounded-md border text-sm focus:ring focus:border-violet-400 form-input-themed"
|
|
placeholder="页码"
|
|
/>
|
|
<button
|
|
id="goToPageBtn"
|
|
class="px-3 py-1 bg-violet-600 hover:bg-violet-700 text-white text-sm rounded-md transition"
|
|
>
|
|
跳转
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scroll buttons are now in base.html -->
|
|
<div class="scroll-buttons">
|
|
<button class="scroll-button" onclick="scrollToTop()" title="回到顶部">
|
|
<i class="fas fa-chevron-up"></i>
|
|
</button>
|
|
<button class="scroll-button" onclick="scrollToBottom()" title="滚动到底部">
|
|
<i class="fas fa-chevron-down"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Notification component is now in base.html (use id="notification") -->
|
|
<div id="notification" class="notification"></div>
|
|
<!-- Footer is now in base.html -->
|
|
|
|
<!-- 日志详情模态框 -->
|
|
<div id="logDetailModal" class="modal">
|
|
<div
|
|
class="w-full max-w-6xl mx-auto rounded-2xl shadow-2xl overflow-hidden animate-fade-in"
|
|
style="
|
|
background-color: rgba(70, 50, 150, 0.95);
|
|
color: #ffffff;
|
|
border: 1px solid rgba(120, 100, 200, 0.4);
|
|
"
|
|
>
|
|
<div class="p-6">
|
|
<div
|
|
class="flex justify-between items-center pb-4 mb-4"
|
|
style="border-bottom: 1px solid rgba(120, 100, 200, 0.4)"
|
|
>
|
|
<h2 class="text-xl font-bold text-gray-100">错误日志详情</h2>
|
|
<button
|
|
id="closeLogDetailModalBtn"
|
|
class="text-gray-300 hover:text-gray-100 text-xl"
|
|
>
|
|
×
|
|
</button>
|
|
</div>
|
|
|
|
<div class="space-y-4 max-h-[60vh] overflow-y-auto p-1">
|
|
<div
|
|
class="p-4 rounded-lg relative group"
|
|
style="background-color: rgba(80, 60, 160, 0.3)"
|
|
>
|
|
<h6 class="text-sm font-semibold text-violet-200 mb-1">
|
|
Gemini密钥:
|
|
</h6>
|
|
<pre
|
|
id="modalGeminiKey"
|
|
class="font-mono text-sm p-3 rounded overflow-x-auto"
|
|
style="background-color: rgba(0, 0, 0, 0.2); color: #e5e7eb"
|
|
></pre>
|
|
<button
|
|
class="copy-btn absolute top-2 right-2 hover:bg-gray-600 text-gray-300 p-1.5 rounded opacity-0 group-hover:opacity-100 transition-opacity"
|
|
style="background-color: rgba(0, 0, 0, 0.3)"
|
|
data-target="modalGeminiKey"
|
|
title="复制密钥"
|
|
>
|
|
<i class="far fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="p-4 rounded-lg relative group"
|
|
style="background-color: rgba(80, 60, 160, 0.3)"
|
|
>
|
|
<h6 class="text-sm font-semibold text-violet-200 mb-1">错误类型:</h6>
|
|
<p id="modalErrorType" class="text-red-300 font-medium pr-8"></p>
|
|
<button
|
|
class="copy-btn absolute top-2 right-2 hover:bg-gray-600 text-gray-300 p-1.5 rounded opacity-0 group-hover:opacity-100 transition-opacity"
|
|
style="background-color: rgba(0, 0, 0, 0.3)"
|
|
data-target="modalErrorType"
|
|
title="复制错误类型"
|
|
>
|
|
<i class="far fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="p-4 rounded-lg relative group"
|
|
style="background-color: rgba(80, 60, 160, 0.3)"
|
|
>
|
|
<h6 class="text-sm font-semibold text-violet-200 mb-1">错误日志:</h6>
|
|
<pre
|
|
id="modalErrorLog"
|
|
class="font-mono text-sm p-3 rounded overflow-x-auto whitespace-pre-wrap"
|
|
style="background-color: rgba(0, 0, 0, 0.2); color: #e5e7eb"
|
|
></pre>
|
|
<button
|
|
class="copy-btn absolute top-2 right-2 hover:bg-gray-600 text-gray-300 p-1.5 rounded opacity-0 group-hover:opacity-100 transition-opacity"
|
|
style="background-color: rgba(0, 0, 0, 0.3)"
|
|
data-target="modalErrorLog"
|
|
title="复制错误日志"
|
|
>
|
|
<i class="far fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="p-4 rounded-lg relative group"
|
|
style="background-color: rgba(80, 60, 160, 0.3)"
|
|
>
|
|
<h6 class="text-sm font-semibold text-violet-200 mb-1">请求消息:</h6>
|
|
<pre
|
|
id="modalRequestMsg"
|
|
class="font-mono text-sm p-3 rounded overflow-x-auto whitespace-pre-wrap"
|
|
style="background-color: rgba(0, 0, 0, 0.2); color: #e5e7eb"
|
|
></pre>
|
|
<button
|
|
class="copy-btn absolute top-2 right-2 hover:bg-gray-600 text-gray-300 p-1.5 rounded opacity-0 group-hover:opacity-100 transition-opacity"
|
|
style="background-color: rgba(0, 0, 0, 0.3)"
|
|
data-target="modalRequestMsg"
|
|
title="复制请求消息"
|
|
>
|
|
<i class="far fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="p-4 rounded-lg relative group"
|
|
style="background-color: rgba(80, 60, 160, 0.3)"
|
|
>
|
|
<h6 class="text-sm font-semibold text-violet-200 mb-1">模型名称:</h6>
|
|
<p id="modalModelName" class="font-medium pr-8 text-gray-200"></p>
|
|
<button
|
|
class="copy-btn absolute top-2 right-2 hover:bg-gray-600 text-gray-300 p-1.5 rounded opacity-0 group-hover:opacity-100 transition-opacity"
|
|
style="background-color: rgba(0, 0, 0, 0.3)"
|
|
data-target="modalModelName"
|
|
title="复制模型名称"
|
|
>
|
|
<i class="far fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
class="p-4 rounded-lg relative group"
|
|
style="background-color: rgba(80, 60, 160, 0.3)"
|
|
>
|
|
<h6 class="text-sm font-semibold text-violet-200 mb-1">请求时间:</h6>
|
|
<p id="modalRequestTime" class="font-medium pr-8 text-gray-200"></p>
|
|
<button
|
|
class="copy-btn absolute top-2 right-2 hover:bg-gray-600 text-gray-300 p-1.5 rounded opacity-0 group-hover:opacity-100 transition-opacity"
|
|
style="background-color: rgba(0, 0, 0, 0.3)"
|
|
data-target="modalRequestTime"
|
|
title="复制请求时间"
|
|
>
|
|
<i class="far fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="flex justify-end mt-6 pt-4"
|
|
style="border-top: 1px solid rgba(120, 100, 200, 0.4)"
|
|
>
|
|
<button
|
|
type="button"
|
|
id="closeModalFooterBtn"
|
|
class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-6 py-2 rounded-lg font-medium transition"
|
|
>
|
|
关闭
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 删除确认模态框 -->
|
|
<div id="deleteConfirmModal" class="modal">
|
|
<div
|
|
class="w-full max-w-md mx-auto rounded-xl shadow-xl overflow-hidden animate-fade-in"
|
|
style="
|
|
background-color: rgba(70, 50, 150, 0.95);
|
|
color: #ffffff;
|
|
border: 1px solid rgba(120, 100, 200, 0.4);
|
|
"
|
|
>
|
|
<div class="p-6">
|
|
<div
|
|
class="flex justify-between items-center pb-3 mb-4"
|
|
style="border-bottom: 1px solid rgba(120, 100, 200, 0.4)"
|
|
>
|
|
<h2 class="text-lg font-semibold text-gray-100">确认删除</h2>
|
|
<button
|
|
id="closeDeleteConfirmModalBtn"
|
|
class="text-gray-300 hover:text-gray-100 text-xl"
|
|
>
|
|
×
|
|
</button>
|
|
</div>
|
|
<p id="deleteConfirmMessage" class="text-gray-300 mb-6">
|
|
你确定要删除选中的项目吗?此操作不可恢复!
|
|
</p>
|
|
<div class="flex justify-end gap-3">
|
|
<button
|
|
id="cancelDeleteBtn"
|
|
type="button"
|
|
class="bg-gray-500 bg-opacity-50 hover:bg-opacity-70 text-gray-200 px-5 py-2 rounded-lg font-medium transition"
|
|
>
|
|
取消
|
|
</button>
|
|
<button
|
|
id="confirmDeleteBtn"
|
|
type="button"
|
|
class="bg-red-600 hover:bg-red-700 text-white px-5 py-2 rounded-lg font-medium transition"
|
|
>
|
|
确认删除
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %} {% block body_scripts %}
|
|
<script src="/static/js/error_logs.js"></script>
|
|
<script>
|
|
// error_logs.html specific JS initialization (if any)
|
|
// e.g., initialize date pickers or other elements if needed
|
|
// The main logic is in error_logs.js
|
|
</script>
|
|
{% endblock %}
|