mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-07-04 14:21:27 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d9c99bda2 | ||
|
|
ab701f9415 | ||
|
|
c3e0d4b64f |
41
README.md
41
README.md
@@ -272,28 +272,45 @@ uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
|||||||
|
|
||||||
### Web界面功能
|
### Web界面功能
|
||||||
|
|
||||||
#### 验证页面
|
#### 验证页面 (auth.html)
|
||||||
|
|
||||||
- **URL**: `/auth`
|
- **URL**: `/auth`
|
||||||
- **说明**: 提供了一个简洁的Web界面用于验证访问令牌
|
- **说明**: 提供了一个简洁的Web界面用于验证访问令牌
|
||||||
- **功能**:
|
- **功能特点**:
|
||||||
- 美观的用户界面,支持响应式设计
|
- 现代化的渐变背景设计
|
||||||
|
- 响应式布局,完美支持移动端
|
||||||
|
- 毛玻璃效果的卡片设计
|
||||||
|
- 优雅的动画效果(淡入、滑动、悬浮)
|
||||||
- 安全的令牌验证机制
|
- 安全的令牌验证机制
|
||||||
- 错误提示功能
|
- 清晰的错误提示功能
|
||||||
- 支持移动端访问
|
- PWA支持,可安装为本地应用
|
||||||
|
- 底部版权信息和GitHub链接
|
||||||
|
- 支持暗色主题适配
|
||||||
|
|
||||||
#### API密钥状态管理
|
#### API密钥状态管理 (keys_status.html)
|
||||||
|
|
||||||
- **URL**: `/v1/keys/list`
|
- **URL**: `/v1/keys/list`
|
||||||
- **Method**: `GET`
|
- **Method**: `GET`
|
||||||
- **Header**: `Authorization: Bearer <your-auth-token>`
|
- **Header**: `Authorization: Bearer <your-auth-token>`
|
||||||
- **说明**:
|
- **功能特点**:
|
||||||
- 只有使用 `AUTH_TOKEN` 才能访问此接口
|
- 只有使用 `AUTH_TOKEN` 才能访问此接口
|
||||||
- 提供了可视化的Web界面展示API密钥状态
|
- 分类展示API密钥状态(有效/无效)
|
||||||
- 支持查看有效和无效的API密钥列表
|
- 可折叠的密钥列表分组
|
||||||
- 显示每个密钥的失败次数统计
|
- 每个密钥显示:
|
||||||
- 提供一键复制功能(支持复制单个密钥或批量复制)
|
- 状态标识(有效/无效)
|
||||||
- 实时显示密钥总数统计
|
- 密钥内容
|
||||||
|
- 失败次数统计
|
||||||
|
- 高级功能:
|
||||||
|
- 一键复制单个密钥
|
||||||
|
- 批量复制分组密钥(JSON格式)
|
||||||
|
- 实时刷新功能
|
||||||
|
- 回到顶部/底部快捷按钮
|
||||||
|
- 界面特性:
|
||||||
|
- 响应式设计,适配各种屏幕
|
||||||
|
- 优雅的动画效果
|
||||||
|
- 操作反馈(复制成功提示)
|
||||||
|
- PWA支持
|
||||||
|
- 暗色主题适配
|
||||||
|
|
||||||
### 图片生成 (Image Generation)
|
### 图片生成 (Image Generation)
|
||||||
|
|
||||||
|
|||||||
@@ -244,5 +244,39 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
.copyright {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
padding: 10px 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2c3e50;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
border-top: 1px solid rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.copyright a {
|
||||||
|
color: #764ba2;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
}
|
||||||
|
.copyright a:hover {
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
.copyright img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="copyright">
|
||||||
|
© <script>document.write(new Date().getFullYear())</script> by <a href="https://linux.do/u/snaily" target="_blank"><img src="https://linux.do/user_avatar/linux.do/snaily/288/306510_2.gif" alt="snaily">snaily</a> |
|
||||||
|
<a href="https://github.com/snailyp/gemini-balance" target="_blank"><i class="fab fa-github"></i> GitHub</a>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -31,6 +31,14 @@
|
|||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: calc(100vh - 40px);
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
.container::-webkit-scrollbar {
|
||||||
|
display: none; /* Chrome, Safari, Opera */
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
@@ -154,13 +162,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.key-list .key-content {
|
.key-list .key-content {
|
||||||
transition: max-height 0.3s ease-out;
|
transition: all 0.3s ease-out;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: 2000px;
|
height: auto;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.key-list .key-content.collapsed {
|
.key-list .key-content.collapsed {
|
||||||
max-height: 0;
|
height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
@@ -288,13 +300,13 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
display: flex;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
.scroll-btn {
|
.scroll-btn {
|
||||||
background: rgba(118, 75, 162, 0.9);
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
color: white;
|
color: white;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
@@ -310,7 +322,7 @@
|
|||||||
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
||||||
}
|
}
|
||||||
.scroll-btn:hover {
|
.scroll-btn:hover {
|
||||||
background: rgba(102, 126, 234, 0.9);
|
background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
.scroll-btn:active {
|
.scroll-btn:active {
|
||||||
@@ -525,15 +537,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scrollToTop() {
|
function scrollToTop() {
|
||||||
window.scrollTo({
|
const container = document.querySelector('.container');
|
||||||
|
container.scrollTo({
|
||||||
top: 0,
|
top: 0,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollToBottom() {
|
function scrollToBottom() {
|
||||||
window.scrollTo({
|
const container = document.querySelector('.container');
|
||||||
top: document.documentElement.scrollHeight,
|
container.scrollTo({
|
||||||
|
top: container.scrollHeight,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -578,5 +592,39 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
.copyright {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
padding: 10px 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2c3e50;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
border-top: 1px solid rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.copyright a {
|
||||||
|
color: #764ba2;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
}
|
||||||
|
.copyright a:hover {
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
.copyright img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="copyright">
|
||||||
|
© <script>document.write(new Date().getFullYear())</script> by <a href="https://linux.do/u/snaily" target="_blank"><img src="https://linux.do/user_avatar/linux.do/snaily/288/306510_2.gif" alt="snaily">snaily</a> |
|
||||||
|
<a href="https://github.com/snailyp/gemini-balance" target="_blank"><i class="fab fa-github"></i> GitHub</a>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user