mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-05-22 16:59:33 +08:00
feat: 为无效密钥列表添加筛选和搜索功能
- 添加无效密钥的失败次数筛选控件 - 添加无效密钥的搜索框和每页显示数量选择器 - 实现无效密钥列表的筛选、搜索和分页功能 - 优化相关CSS样式以保持界面一致性
This commit is contained in:
@@ -862,6 +862,12 @@ function initializeKeyFilterControls() {
|
||||
if (thresholdInput) {
|
||||
thresholdInput.addEventListener("input", filterValidKeys);
|
||||
}
|
||||
|
||||
// 为无效密钥添加筛选控件监听器
|
||||
const invalidThresholdInput = document.getElementById("invalidFailCountThreshold");
|
||||
if (invalidThresholdInput) {
|
||||
invalidThresholdInput.addEventListener("input", () => fetchAndDisplayKeys('invalid', 1));
|
||||
}
|
||||
}
|
||||
|
||||
function initializeGlobalBatchVerificationHandlers() {
|
||||
@@ -1174,13 +1180,14 @@ async function fetchAndDisplayKeys(type, page = 1) {
|
||||
// Show loading indicator
|
||||
listElement.innerHTML = `<li><div class="text-center py-4 col-span-full"><i class="fas fa-spinner fa-spin"></i> Loading...</div></li>`;
|
||||
|
||||
const itemsPerPageSelect = document.getElementById("itemsPerPageSelect");
|
||||
// 根据类型选择对应的控件
|
||||
const itemsPerPageSelect = document.getElementById(type === 'valid' ? "itemsPerPageSelect" : "invalidItemsPerPageSelect");
|
||||
const limit = itemsPerPageSelect ? parseInt(itemsPerPageSelect.value, 10) : 10;
|
||||
|
||||
const searchInput = document.getElementById("keySearchInput");
|
||||
const searchInput = document.getElementById(type === 'valid' ? "keySearchInput" : "invalidKeySearchInput");
|
||||
const searchTerm = searchInput ? searchInput.value : '';
|
||||
|
||||
const thresholdInput = document.getElementById("failCountThreshold");
|
||||
const thresholdInput = document.getElementById(type === 'valid' ? "failCountThreshold" : "invalidFailCountThreshold");
|
||||
const failCountThreshold = thresholdInput ? (thresholdInput.value === '' ? null : parseInt(thresholdInput.value, 10)) : null;
|
||||
|
||||
try {
|
||||
@@ -1319,6 +1326,7 @@ function initializeKeyPaginationAndSearch() {
|
||||
const debouncedFetchValidKeys = debounce(() => fetchAndDisplayKeys('valid', 1), 300);
|
||||
const debouncedFetchInvalidKeys = debounce(() => fetchAndDisplayKeys('invalid', 1), 300);
|
||||
|
||||
// 有效密钥的搜索和筛选控件
|
||||
const searchInput = document.getElementById("keySearchInput");
|
||||
if (searchInput) {
|
||||
searchInput.addEventListener("input", debouncedFetchValidKeys);
|
||||
@@ -1333,6 +1341,23 @@ function initializeKeyPaginationAndSearch() {
|
||||
if (itemsPerPageSelect) {
|
||||
itemsPerPageSelect.addEventListener("change", () => {
|
||||
fetchAndDisplayKeys('valid', 1);
|
||||
});
|
||||
}
|
||||
|
||||
// 无效密钥的搜索和筛选控件
|
||||
const invalidSearchInput = document.getElementById("invalidKeySearchInput");
|
||||
if (invalidSearchInput) {
|
||||
invalidSearchInput.addEventListener("input", debouncedFetchInvalidKeys);
|
||||
}
|
||||
|
||||
const invalidThresholdInput = document.getElementById("invalidFailCountThreshold");
|
||||
if (invalidThresholdInput) {
|
||||
invalidThresholdInput.addEventListener("input", debouncedFetchInvalidKeys);
|
||||
}
|
||||
|
||||
const invalidItemsPerPageSelect = document.getElementById("invalidItemsPerPageSelect");
|
||||
if (invalidItemsPerPageSelect) {
|
||||
invalidItemsPerPageSelect.addEventListener("change", () => {
|
||||
fetchAndDisplayKeys('invalid', 1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -875,7 +875,8 @@ endblock %} {% block head_extra_styles %}
|
||||
}
|
||||
|
||||
/* Fix specific pagination elements by ID and class */
|
||||
#validKeysPageSize, #invalidKeysPageSize {
|
||||
#validKeysPageSize, #invalidKeysPageSize,
|
||||
#itemsPerPageSelect, #invalidItemsPerPageSelect {
|
||||
background-color: rgba(255, 255, 255, 0.95) !important;
|
||||
color: #374151 !important; /* gray-700 */
|
||||
border: 1px solid rgba(0, 0, 0, 0.12) !important;
|
||||
@@ -884,7 +885,8 @@ endblock %} {% block head_extra_styles %}
|
||||
font-size: 0.875rem !important; /* text-sm */
|
||||
}
|
||||
|
||||
#validKeysPageSize:focus, #invalidKeysPageSize:focus {
|
||||
#validKeysPageSize:focus, #invalidKeysPageSize:focus,
|
||||
#itemsPerPageSelect:focus, #invalidItemsPerPageSelect:focus {
|
||||
border-color: #3b82f6 !important; /* blue-500 */
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
|
||||
outline: none !important;
|
||||
@@ -947,7 +949,10 @@ endblock %} {% block head_extra_styles %}
|
||||
label[for="selectAllInvalid"],
|
||||
label[for="failCountThreshold"],
|
||||
label[for="keySearchInput"],
|
||||
label[for="itemsPerPageSelect"] {
|
||||
label[for="itemsPerPageSelect"],
|
||||
label[for="invalidFailCountThreshold"],
|
||||
label[for="invalidKeySearchInput"],
|
||||
label[for="invalidItemsPerPageSelect"] {
|
||||
color: #1f2937 !important; /* gray-800 for maximum contrast */
|
||||
font-weight: 600 !important; /* font-semibold for better visibility */
|
||||
text-shadow: none !important;
|
||||
@@ -1434,12 +1439,72 @@ endblock %} {% block head_extra_styles %}
|
||||
无效密钥列表 ({{ invalid_key_count }})
|
||||
</h2>
|
||||
</div>
|
||||
<!-- Middle: Filters and Search (Allow wrapping) -->
|
||||
<div
|
||||
class="flex items-center gap-x-4 gap-y-2 flex-grow flex-wrap justify-start md:justify-center"
|
||||
>
|
||||
<!-- Allow wrapping, center on medium+ -->
|
||||
<!-- 失败次数筛选 -->
|
||||
<div class="flex items-center gap-1">
|
||||
<label
|
||||
for="invalidFailCountThreshold"
|
||||
class="text-sm select-none whitespace-nowrap font-semibold"
|
||||
style="color: #1f2937 !important;"
|
||||
>失败次数≥</label
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
id="invalidFailCountThreshold"
|
||||
value="0"
|
||||
min="0"
|
||||
class="form-input h-7 w-16 px-2 py-1 text-sm border rounded focus:ring-primary-500 focus:border-primary-500"
|
||||
onclick="event.stopPropagation();"
|
||||
/>
|
||||
</div>
|
||||
<!-- 密钥搜索 -->
|
||||
<div class="flex items-center gap-1">
|
||||
<label
|
||||
for="invalidKeySearchInput"
|
||||
class="text-sm select-none whitespace-nowrap font-semibold"
|
||||
style="color: #1f2937 !important;"
|
||||
><i class="fas fa-search mr-1"></i>搜索</label
|
||||
>
|
||||
<input
|
||||
type="search"
|
||||
id="invalidKeySearchInput"
|
||||
placeholder="输入密钥..."
|
||||
class="form-input h-7 w-32 px-2 py-1 text-sm border rounded focus:ring-primary-500 focus:border-primary-500"
|
||||
onclick="event.stopPropagation();"
|
||||
/>
|
||||
</div>
|
||||
<!-- 每页显示数量 -->
|
||||
<div class="flex items-center gap-1">
|
||||
<label
|
||||
for="invalidItemsPerPageSelect"
|
||||
class="text-sm select-none whitespace-nowrap font-semibold"
|
||||
style="color: #1f2937 !important;"
|
||||
>每页</label
|
||||
>
|
||||
<select
|
||||
id="invalidItemsPerPageSelect"
|
||||
class="form-select h-7 px-2 py-1 text-sm border rounded focus:ring-primary-500 focus:border-primary-500"
|
||||
onclick="event.stopPropagation();"
|
||||
>
|
||||
<option value="10">10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="500">500</option>
|
||||
</select>
|
||||
<span class="text-sm select-none font-semibold" style="color: #1f2937 !important;">项</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right side: Select All -->
|
||||
<div
|
||||
class="flex items-center gap-1 ml-auto flex-shrink-0"
|
||||
class="flex items-center gap-1 flex-shrink-0"
|
||||
onclick="event.stopPropagation();"
|
||||
>
|
||||
<!-- Use ml-auto, Prevent shrinking -->
|
||||
<!-- Prevent shrinking -->
|
||||
<input
|
||||
type="checkbox"
|
||||
id="selectAllInvalid"
|
||||
|
||||
Reference in New Issue
Block a user