|
|
<!DOCTYPE html> |
|
|
<html lang="zh-CN"> |
|
|
<head> |
|
|
<meta charset="UTF-8" /> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|
|
<title>{% block title %}Gemini Balance{% endblock %}</title> |
|
|
<link rel="manifest" href="{{ static_url('manifest.json') }}" /> |
|
|
<meta name="theme-color" content="#4F46E5" /> |
|
|
<meta name="apple-mobile-web-app-capable" content="yes" /> |
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> |
|
|
<meta name="apple-mobile-web-app-title" content="GBalance" /> |
|
|
<link rel="icon" href="{{ static_url('icons/icon-192x192.png') }}" /> |
|
|
<link |
|
|
href="{{ static_url('css/fonts.css') }}" |
|
|
rel="stylesheet" |
|
|
/> |
|
|
<link |
|
|
rel="stylesheet" |
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" |
|
|
/> |
|
|
<script src="{{ static_url('js/tailwindcss.js') }}"></script> |
|
|
<script> |
|
|
tailwind.config = { |
|
|
theme: { |
|
|
extend: { |
|
|
colors: { |
|
|
primary: { |
|
|
50: "#eef2ff", |
|
|
100: "#e0e7ff", |
|
|
200: "#c7d2fe", |
|
|
300: "#a5b4fc", |
|
|
400: "#818cf8", |
|
|
500: "#6366f1", |
|
|
600: "#4f46e5", |
|
|
700: "#4338ca", |
|
|
800: "#3730a3", |
|
|
900: "#312e81", |
|
|
}, |
|
|
success: { |
|
|
50: "#ecfdf5", |
|
|
500: "#10b981", |
|
|
600: "#059669", |
|
|
}, |
|
|
danger: { |
|
|
50: "#fef2f2", |
|
|
500: "#ef4444", |
|
|
600: "#dc2626", |
|
|
}, |
|
|
}, |
|
|
fontFamily: { |
|
|
sans: ["Inter", "sans-serif"], |
|
|
mono: [ |
|
|
"JetBrains Mono", |
|
|
"SFMono-Regular", |
|
|
"Menlo", |
|
|
"Monaco", |
|
|
"Consolas", |
|
|
"monospace", |
|
|
], |
|
|
}, |
|
|
animation: { |
|
|
"fade-in": "fadeIn 0.5s ease-out", |
|
|
"slide-up": "slideUp 0.5s ease-out", |
|
|
"slide-down": "slideDown 0.5s ease-out", |
|
|
shake: "shake 0.5s ease-in-out", |
|
|
spin: "spin 1s linear infinite", |
|
|
}, |
|
|
keyframes: { |
|
|
fadeIn: { |
|
|
"0%": { opacity: "0" }, |
|
|
"100%": { opacity: "1" }, |
|
|
}, |
|
|
slideUp: { |
|
|
"0%": { transform: "translateY(20px)", opacity: "0" }, |
|
|
"100%": { transform: "translateY(0)", opacity: "1" }, |
|
|
}, |
|
|
slideDown: { |
|
|
"0%": { transform: "translateY(-20px)", opacity: "0" }, |
|
|
"100%": { transform: "translateY(0)", opacity: "1" }, |
|
|
}, |
|
|
shake: { |
|
|
"0%, 100%": { transform: "translateX(0)" }, |
|
|
"25%": { transform: "translateX(-5px)" }, |
|
|
"75%": { transform: "translateX(5px)" }, |
|
|
}, |
|
|
spin: { |
|
|
"0%": { transform: "rotate(0deg)" }, |
|
|
"100%": { transform: "rotate(360deg)" }, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}; |
|
|
</script> |
|
|
<style> |
|
|
.glass-card { |
|
|
background: rgba(255, 255, 255, 0.95); |
|
|
backdrop-filter: blur(16px); |
|
|
-webkit-backdrop-filter: blur(16px); |
|
|
border: 1px solid rgba(0, 0, 0, 0.08); |
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
|
|
} |
|
|
.bg-gradient { |
|
|
background: #ffffff; |
|
|
} |
|
|
|
|
|
::-webkit-scrollbar { |
|
|
width: 8px; |
|
|
height: 8px; |
|
|
} |
|
|
::-webkit-scrollbar-track { |
|
|
background: rgba(243, 244, 246, 0.8); |
|
|
border-radius: 10px; |
|
|
} |
|
|
::-webkit-scrollbar-thumb { |
|
|
background: rgba(107, 114, 128, 0.6); |
|
|
border-radius: 10px; |
|
|
} |
|
|
::-webkit-scrollbar-thumb:hover { |
|
|
background: rgba(75, 85, 99, 0.8); |
|
|
} |
|
|
|
|
|
.modal { |
|
|
display: none; |
|
|
position: fixed; |
|
|
z-index: 50; |
|
|
left: 0; |
|
|
top: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background-color: rgba(0,0,0,0.5); |
|
|
backdrop-filter: blur(4px); |
|
|
} |
|
|
.modal.show { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
} |
|
|
|
|
|
|
|
|
.modal .w-full[style*="background-color: rgba(70, 50, 150"], |
|
|
.modal .w-full[style*="background-color: rgba(80, 60, 160"] { |
|
|
background-color: rgba(255, 255, 255, 0.98) !important; |
|
|
color: #374151 !important; |
|
|
border: 1px solid rgba(0, 0, 0, 0.08) !important; |
|
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !important; |
|
|
} |
|
|
|
|
|
|
|
|
.modal .text-gray-100, .modal h2.text-gray-100, .modal h3.text-gray-100 { |
|
|
color: #1f2937 !important; |
|
|
font-weight: 600 !important; |
|
|
} |
|
|
|
|
|
.modal .text-gray-200, .modal .text-gray-300 { |
|
|
color: #6b7280 !important; |
|
|
} |
|
|
|
|
|
.modal .text-gray-300:hover { |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.modal .bg-violet-600, .modal button.bg-violet-600 { |
|
|
background-color: #3b82f6 !important; |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
.modal .bg-violet-600:hover, .modal button.bg-violet-600:hover { |
|
|
background-color: #2563eb !important; |
|
|
} |
|
|
|
|
|
|
|
|
.modal .bg-blue-500, .modal button.bg-blue-500, |
|
|
.modal .bg-blue-600, .modal button.bg-blue-600, |
|
|
.modal .bg-blue-700, .modal button.bg-blue-700 { |
|
|
background-color: #3b82f6 !important; |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
.modal .bg-blue-500:hover, .modal button.bg-blue-500:hover, |
|
|
.modal .bg-blue-600:hover, .modal button.bg-blue-600:hover, |
|
|
.modal .bg-blue-700:hover, .modal button.bg-blue-700:hover { |
|
|
background-color: #2563eb !important; |
|
|
} |
|
|
|
|
|
|
|
|
.modal .bg-red-500, .modal button.bg-red-500, |
|
|
.modal .bg-red-600, .modal button.bg-red-600, |
|
|
.modal .bg-red-700, .modal button.bg-red-700 { |
|
|
background-color: #f87171 !important; |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
.modal .bg-red-500:hover, .modal button.bg-red-500:hover, |
|
|
.modal .bg-red-600:hover, .modal button.bg-red-600:hover, |
|
|
.modal .bg-red-700:hover, .modal button.bg-red-700:hover { |
|
|
background-color: #ef4444 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.modal .bg-gray-500, .modal button.bg-gray-500, |
|
|
.modal .bg-gray-600, .modal button.bg-gray-600, |
|
|
.modal .bg-gray-700, .modal button.bg-gray-700 { |
|
|
background-color: #e5e7eb !important; |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
.modal .bg-gray-500:hover, .modal button.bg-gray-500:hover, |
|
|
.modal .bg-gray-600:hover, .modal button.bg-gray-600:hover, |
|
|
.modal .bg-gray-700:hover, .modal button.bg-gray-700:hover { |
|
|
background-color: #d1d5db !important; |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.bg-blue-500, .bg-blue-600, .bg-blue-700, .bg-blue-800, .bg-blue-900, |
|
|
.bg-red-500, .bg-red-600, .bg-red-700, .bg-red-800, .bg-red-900, |
|
|
.bg-green-500, .bg-green-600, .bg-green-700, .bg-green-800, .bg-green-900, |
|
|
.bg-purple-500, .bg-purple-600, .bg-purple-700, .bg-purple-800, .bg-purple-900, |
|
|
.bg-indigo-500, .bg-indigo-600, .bg-indigo-700, .bg-indigo-800, .bg-indigo-900, |
|
|
.bg-violet-500, .bg-violet-600, .bg-violet-700, .bg-violet-800, .bg-violet-900, |
|
|
.bg-sky-500, .bg-sky-600, .bg-sky-700, .bg-sky-800, .bg-sky-900, |
|
|
.bg-teal-500, .bg-teal-600, .bg-teal-700, .bg-teal-800, .bg-teal-900, |
|
|
.bg-gray-700, .bg-gray-800, .bg-gray-900, |
|
|
.bg-slate-500, .bg-slate-600, .bg-slate-700, .bg-slate-800, .bg-slate-900 { |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-gray-50, .bg-gray-100, .bg-gray-200, .bg-gray-300, |
|
|
.bg-white, .bg-transparent { |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-blue-500 *, .bg-blue-600 *, .bg-blue-700 *, .bg-blue-800 *, .bg-blue-900 *, |
|
|
.bg-red-500 *, .bg-red-600 *, .bg-red-700 *, .bg-red-800 *, .bg-red-900 *, |
|
|
.bg-green-500 *, .bg-green-600 *, .bg-green-700 *, .bg-green-800 *, .bg-green-900 *, |
|
|
.bg-purple-500 *, .bg-purple-600 *, .bg-purple-700 *, .bg-purple-800 *, .bg-purple-900 *, |
|
|
.bg-violet-500 *, .bg-violet-600 *, .bg-violet-700 *, .bg-violet-800 *, .bg-violet-900 *, |
|
|
.bg-sky-500 *, .bg-sky-600 *, .bg-sky-700 *, .bg-sky-800 *, .bg-sky-900 *, |
|
|
.bg-teal-500 *, .bg-teal-600 *, .bg-teal-700 *, .bg-teal-800 *, .bg-teal-900 *, |
|
|
.bg-gray-700 *, .bg-gray-800 *, .bg-gray-900 *, |
|
|
.bg-slate-500 *, .bg-slate-600 *, .bg-slate-700 *, .bg-slate-800 *, .bg-slate-900 * { |
|
|
color: inherit !important; |
|
|
} |
|
|
|
|
|
|
|
|
select, input[type="text"], input[type="number"], input[type="search"], |
|
|
input[type="email"], input[type="password"], input[type="datetime-local"], |
|
|
textarea, .form-input, .form-select { |
|
|
background-color: rgba(255, 255, 255, 0.95) !important; |
|
|
color: #374151 !important; |
|
|
border: 1px solid rgba(0, 0, 0, 0.12) !important; |
|
|
border-radius: 0.375rem !important; |
|
|
} |
|
|
|
|
|
select:focus, input:focus, textarea:focus, |
|
|
.form-input:focus, .form-select:focus { |
|
|
border-color: #3b82f6 !important; |
|
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important; |
|
|
outline: none !important; |
|
|
} |
|
|
|
|
|
|
|
|
select option { |
|
|
background-color: rgba(255, 255, 255, 0.98) !important; |
|
|
color: #374151 !important; |
|
|
padding: 8px !important; |
|
|
} |
|
|
|
|
|
|
|
|
.pagination-button, .pagination a, .pagination button { |
|
|
background-color: rgba(255, 255, 255, 0.9) !important; |
|
|
color: #374151 !important; |
|
|
border: 1px solid rgba(0, 0, 0, 0.08) !important; |
|
|
transition: all 0.15s ease-in-out !important; |
|
|
} |
|
|
|
|
|
.pagination-button:hover, .pagination a:hover, .pagination button:hover { |
|
|
background-color: rgba(229, 231, 235, 1) !important; |
|
|
border-color: rgba(0, 0, 0, 0.12) !important; |
|
|
transform: translateY(-1px) !important; |
|
|
} |
|
|
|
|
|
.pagination-button.active, .pagination a.active, .pagination button.active { |
|
|
background-color: #3b82f6 !important; |
|
|
color: #ffffff !important; |
|
|
border-color: #2563eb !important; |
|
|
font-weight: 600 !important; |
|
|
} |
|
|
|
|
|
.loading-spin { |
|
|
animation: spin 1s linear infinite; |
|
|
} |
|
|
@keyframes spin { |
|
|
from { transform: rotate(0deg); } |
|
|
to { transform: rotate(360deg); } |
|
|
} |
|
|
|
|
|
.notification { |
|
|
position: fixed; |
|
|
bottom: 5rem; |
|
|
left: 50%; |
|
|
transform: translateX(-50%); |
|
|
padding: 0.75rem 1.25rem; |
|
|
border-radius: 0.5rem; |
|
|
background-color: rgba(34, 197, 94, 0.95); |
|
|
color: white; |
|
|
font-weight: 500; |
|
|
z-index: 1000; |
|
|
opacity: 0; |
|
|
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out; |
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); |
|
|
} |
|
|
.notification.show { |
|
|
opacity: 1; |
|
|
transform: translate(-50%, 0); |
|
|
} |
|
|
.notification.error { |
|
|
background-color: rgba(239, 68, 68, 0.95); |
|
|
} |
|
|
|
|
|
.scroll-buttons { |
|
|
position: fixed; |
|
|
right: 1.25rem; |
|
|
bottom: 5rem; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 0.5rem; |
|
|
z-index: 10; |
|
|
} |
|
|
.scroll-button { |
|
|
width: 2.5rem; |
|
|
height: 2.5rem; |
|
|
background-color: #3b82f6; |
|
|
color: white; |
|
|
border-radius: 9999px; |
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
transition: all 0.3s ease-in-out; |
|
|
} |
|
|
.scroll-button:hover { |
|
|
background-color: #2563eb; |
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); |
|
|
} |
|
|
|
|
|
|
|
|
.text-gray-200, .text-gray-300, .text-gray-400 { |
|
|
color: #6b7280 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-primary-600, .bg-primary-700 { |
|
|
background-color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
.text-primary-600, .text-primary-700 { |
|
|
color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
.border-primary-500, .focus\\:border-primary-500 { |
|
|
border-color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
.ring-primary-200, .focus\\:ring-primary-200 { |
|
|
--tw-ring-color: rgba(59, 130, 246, 0.2) !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-violet-50, .bg-violet-100, .bg-violet-200, .bg-violet-300, .bg-violet-400, .bg-violet-500, .bg-violet-600, .bg-violet-700, .bg-violet-800, .bg-violet-900 { |
|
|
background-color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
.text-violet-50, .text-violet-100, .text-violet-200, .text-violet-300, .text-violet-400, .text-violet-500, .text-violet-600, .text-violet-700, .text-violet-800, .text-violet-900 { |
|
|
color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
.border-violet-50, .border-violet-100, .border-violet-200, .border-violet-300, .border-violet-400, .border-violet-500, .border-violet-600, .border-violet-700, .border-violet-800, .border-violet-900 { |
|
|
border-color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.bg-blue-500, .bg-blue-600, .bg-blue-700, .bg-blue-800, .bg-blue-900, |
|
|
button.bg-blue-500, button.bg-blue-600, button.bg-blue-700, button.bg-blue-800, button.bg-blue-900 { |
|
|
background-color: #3b82f6 !important; |
|
|
} |
|
|
|
|
|
.bg-blue-500:hover, .bg-blue-600:hover, .bg-blue-700:hover, .bg-blue-800:hover, .bg-blue-900:hover, |
|
|
button.bg-blue-500:hover, button.bg-blue-600:hover, button.bg-blue-700:hover, button.bg-blue-800:hover, button.bg-blue-900:hover, |
|
|
.hover\\:bg-blue-600:hover, .hover\\:bg-blue-700:hover, .hover\\:bg-blue-800:hover { |
|
|
background-color: #2563eb !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-red-500, .bg-red-600, .bg-red-700, .bg-red-800, .bg-red-900, |
|
|
button.bg-red-500, button.bg-red-600, button.bg-red-700, button.bg-red-800, button.bg-red-900 { |
|
|
background-color: #f87171 !important; |
|
|
} |
|
|
|
|
|
.bg-red-500:hover, .bg-red-600:hover, .bg-red-700:hover, .bg-red-800:hover, .bg-red-900:hover, |
|
|
button.bg-red-500:hover, button.bg-red-600:hover, button.bg-red-700:hover, button.bg-red-800:hover, button.bg-red-900:hover, |
|
|
.hover\\:bg-red-600:hover, .hover\\:bg-red-700:hover, .hover\\:bg-red-800:hover { |
|
|
background-color: #ef4444 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-gray-500, .bg-gray-600, .bg-gray-700, .bg-gray-800, .bg-gray-900, |
|
|
button.bg-gray-500, button.bg-gray-600, button.bg-gray-700, button.bg-gray-800, button.bg-gray-900 { |
|
|
background-color: #e5e7eb !important; |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
.bg-gray-500:hover, .bg-gray-600:hover, .bg-gray-700:hover, .bg-gray-800:hover, .bg-gray-900:hover, |
|
|
button.bg-gray-500:hover, button.bg-gray-600:hover, button.bg-gray-700:hover, button.bg-gray-800:hover, button.bg-gray-900:hover, |
|
|
.hover\\:bg-gray-600:hover, .hover\\:bg-gray-700:hover, .hover\\:bg-gray-800:hover { |
|
|
background-color: #d1d5db !important; |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.text-white { |
|
|
color: #374151 !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-blue-500, .bg-blue-600, .bg-blue-700, .bg-blue-800, .bg-blue-900, |
|
|
.bg-red-500, .bg-red-600, .bg-red-700, .bg-red-800, .bg-red-900, |
|
|
.bg-green-500, .bg-green-600, .bg-green-700, .bg-green-800, .bg-green-900, |
|
|
.bg-purple-500, .bg-purple-600, .bg-purple-700, .bg-purple-800, .bg-purple-900, |
|
|
.bg-indigo-500, .bg-indigo-600, .bg-indigo-700, .bg-indigo-800, .bg-indigo-900, |
|
|
.bg-gray-700, .bg-gray-800, .bg-gray-900, |
|
|
.bg-sky-500, .bg-sky-600, .bg-sky-700, .bg-sky-800, .bg-sky-900 { |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
|
|
|
button.bg-blue-500, button.bg-blue-600, button.bg-blue-700, |
|
|
button.bg-red-500, button.bg-red-600, button.bg-red-700, |
|
|
button.bg-green-500, button.bg-green-600, button.bg-green-700, |
|
|
button.bg-sky-500, button.bg-sky-600, button.bg-sky-700, |
|
|
.btn-primary, .btn-danger, .btn-success, .btn-info { |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
|
|
|
.bg-blue-500 *, .bg-blue-600 *, .bg-blue-700 *, |
|
|
.bg-red-500 *, .bg-red-600 *, .bg-red-700 *, |
|
|
.bg-green-500 *, .bg-green-600 *, .bg-green-700 *, |
|
|
.bg-sky-500 *, .bg-sky-600 *, .bg-sky-700 * { |
|
|
color: inherit !important; |
|
|
} |
|
|
|
|
|
{% block head_extra_styles %} |
|
|
{% endblock %} |
|
|
</style> |
|
|
{% block head_extra_scripts %}{% endblock %} |
|
|
</head> |
|
|
<body class="bg-white min-h-screen text-gray-900 pt-6 pb-16"> |
|
|
{% block content %}{% endblock %} |
|
|
|
|
|
|
|
|
<div |
|
|
class="fixed bottom-0 left-0 w-full py-3 bg-white bg-opacity-95 backdrop-blur-md text-sm text-gray-800 border-t border-gray-200 flex flex-col items-center space-y-1" |
|
|
> |
|
|
|
|
|
<div class="flex items-center justify-center space-x-2"> |
|
|
<span>© <span id="copyright-year"></span> by</span> |
|
|
<a |
|
|
href="https://linux.do/u/snaily" |
|
|
target="_blank" |
|
|
class="text-primary-600 hover:text-primary-800 transition duration-300 flex items-center" |
|
|
> |
|
|
<img |
|
|
src="https://linux.do/user_avatar/linux.do/snaily/288/306510_2.gif" |
|
|
alt="snaily" |
|
|
class="inline-block w-5 h-5 rounded-full align-middle mr-1" |
|
|
/>snaily |
|
|
</a> |
|
|
<span class="text-gray-400">|</span> |
|
|
<a |
|
|
href="https://github.com/snailyp/gemini-balance" |
|
|
target="_blank" |
|
|
class="text-primary-600 hover:text-primary-800 transition duration-300 flex items-center" |
|
|
> |
|
|
<i class="fab fa-github mr-1"></i> GitHub |
|
|
</a> |
|
|
</div> |
|
|
|
|
|
<div class="flex items-center justify-center space-x-2 text-xs"> |
|
|
<a |
|
|
href="https://gb-docs.snaily.top/guide/supportme.html" |
|
|
target="_blank" |
|
|
class="text-primary-600 hover:text-primary-800 transition duration-300 flex items-center" |
|
|
> |
|
|
<i class="fas fa-drumstick-bite text-yellow-600 mr-1"></i> 给作者加鸡腿 |
|
|
</a> |
|
|
<span class="text-gray-400">|</span> |
|
|
<a |
|
|
href="https://gb-docs.snaily.top" |
|
|
target="_blank" |
|
|
class="text-primary-600 hover:text-primary-800 transition duration-300 flex items-center" |
|
|
> |
|
|
<i class="fas fa-book mr-1"></i> 在线文档 |
|
|
</a> |
|
|
<span class="text-gray-400">|</span> |
|
|
<a |
|
|
href="https://t.me/+soaHax5lyI0wZDVl" |
|
|
target="_blank" |
|
|
class="text-primary-600 hover:text-primary-800 transition duration-300 flex items-center" |
|
|
> |
|
|
<i class="fab fa-telegram-plane mr-1"></i> 交流群 |
|
|
</a> |
|
|
<span class="text-gray-400">|</span> |
|
|
<span class="text-yellow-600 font-semibold flex items-center"> |
|
|
<i class="fas fa-exclamation-triangle mr-1"></i>免费项目,谨防诈骗 |
|
|
</span> |
|
|
<span id="version-info-container" class="inline-flex items-center"> |
|
|
|
|
|
</span> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
document.getElementById("copyright-year").textContent = |
|
|
new Date().getFullYear(); |
|
|
|
|
|
|
|
|
function scrollToTop() { |
|
|
window.scrollTo({ top: 0, behavior: "smooth" }); |
|
|
} |
|
|
function scrollToBottom() { |
|
|
window.scrollTo({ |
|
|
top: document.body.scrollHeight, |
|
|
behavior: "smooth", |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function showNotification(message, type = "success", duration = 3000) { |
|
|
const notification = |
|
|
document.getElementById("notification") || |
|
|
createNotificationElement(); |
|
|
if (!notification) return; |
|
|
|
|
|
notification.textContent = message; |
|
|
notification.className = "notification show"; |
|
|
if (type === "error") { |
|
|
notification.classList.add("error"); |
|
|
} |
|
|
|
|
|
|
|
|
if (notification.timeoutId) { |
|
|
clearTimeout(notification.timeoutId); |
|
|
} |
|
|
|
|
|
notification.timeoutId = setTimeout(() => { |
|
|
notification.classList.remove("show"); |
|
|
|
|
|
|
|
|
}, duration); |
|
|
} |
|
|
|
|
|
|
|
|
function createNotificationElement() { |
|
|
let notification = document.getElementById("notification"); |
|
|
if (!notification) { |
|
|
notification = document.createElement("div"); |
|
|
notification.id = "notification"; |
|
|
notification.className = "notification"; |
|
|
document.body.appendChild(notification); |
|
|
} |
|
|
return notification; |
|
|
} |
|
|
|
|
|
|
|
|
function refreshPage(button) { |
|
|
if (button) { |
|
|
const icon = button.querySelector("i"); |
|
|
if (icon) { |
|
|
icon.classList.add("loading-spin"); |
|
|
} |
|
|
} |
|
|
setTimeout(() => { |
|
|
window.location.reload(); |
|
|
}, 300); |
|
|
} |
|
|
|
|
|
|
|
|
const versionInfoContainer = document.getElementById( |
|
|
"version-info-container" |
|
|
); |
|
|
|
|
|
async function fetchVersionInfo() { |
|
|
if (!versionInfoContainer) return; |
|
|
versionInfoContainer.innerHTML = |
|
|
'<span class="mx-1">|</span><span class="text-xs text-gray-700">检查更新中...</span>'; |
|
|
|
|
|
try { |
|
|
const response = await fetch("/api/version/check"); |
|
|
if (!response.ok) { |
|
|
throw new Error(`HTTP error! status: ${response.status}`); |
|
|
} |
|
|
const data = await response.json(); |
|
|
|
|
|
let versionHtml = `<span class="mx-1">|</span><span class="text-xs text-gray-800">v${data.current_version}</span>`; |
|
|
if (data.update_available) { |
|
|
versionHtml += ` |
|
|
<span class="mx-1">|</span> |
|
|
<a href="https://github.com/snailyp/gemini-balance/releases/latest" target="_blank" class="text-yellow-600 hover:text-yellow-800 transition duration-300 animate-pulse"> |
|
|
<i class="fas fa-arrow-up"></i> 新版本: v${data.latest_version} |
|
|
</a>`; |
|
|
} else if (data.error_message) { |
|
|
versionHtml += ` |
|
|
<span class="mx-1">|</span> |
|
|
<span class="text-xs text-red-500" title="${data.error_message}">更新检查失败</span>`; |
|
|
} else { |
|
|
versionHtml += `<span class="mx-1">|</span><span class="text-xs text-green-500">已是最新</span>`; |
|
|
} |
|
|
versionInfoContainer.innerHTML = versionHtml; |
|
|
} catch (error) { |
|
|
console.error("Error fetching version info:", error); |
|
|
versionInfoContainer.innerHTML = `<span class="mx-1">|</span><span class="text-xs text-red-500" title="无法连接到服务器或解析响应">更新检查失败</span>`; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fetchVersionInfo(); |
|
|
|
|
|
|
|
|
setInterval(fetchVersionInfo, 3600000); |
|
|
</script> |
|
|
{% block body_scripts %}{% endblock %} |
|
|
</body> |
|
|
</html> |
|
|
|