From ccd97c1066344105ea9bf664dc9309fb0d23786a Mon Sep 17 00:00:00 2001 From: hex2077 Date: Wed, 21 Jan 2026 00:43:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(provider):=20=E6=B7=BB=E5=8A=A0refreshCoun?= =?UTF-8?q?t=E9=87=8D=E7=BD=AE=E9=80=BB=E8=BE=91=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=A8=A1=E5=9E=8B=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(ui): 将模型列表从指南页移动到仪表盘页 fix(api): 移除健康检查中的abortController信号 style(css): 迁移模型列表样式到仪表盘样式文件 --- src/providers/provider-pool-manager.js | 3 +- src/ui-modules/provider-api.js | 1 + src/ui-modules/usage-api.js | 6 +- static/components/section-dashboard.css | 358 +++++++++++++++++++++++ static/components/section-dashboard.html | 22 ++ static/components/section-guide.css | 320 -------------------- static/components/section-guide.html | 24 -- 7 files changed, 388 insertions(+), 346 deletions(-) diff --git a/src/providers/provider-pool-manager.js b/src/providers/provider-pool-manager.js index d182bc3..eaee054 100644 --- a/src/providers/provider-pool-manager.js +++ b/src/providers/provider-pool-manager.js @@ -973,6 +973,7 @@ export class ProviderPoolManager { if (provider) { provider.config.isHealthy = true; provider.config.errorCount = 0; + provider.config.refreshCount = 0; provider.config.lastErrorTime = null; provider.config.lastErrorMessage = null; @@ -1334,7 +1335,7 @@ export class ProviderPoolManager { // 尝试将 signal 注入请求体,供支持的适配器使用 const requestWithSignal = { ...healthCheckRequest, - signal: abortController.signal + // signal: abortController.signal }; await serviceAdapter.generateContent(modelName, requestWithSignal); diff --git a/src/ui-modules/provider-api.js b/src/ui-modules/provider-api.js index 965bd9b..b7d25c6 100644 --- a/src/ui-modules/provider-api.js +++ b/src/ui-modules/provider-api.js @@ -428,6 +428,7 @@ export async function handleResetProviderHealth(req, res, currentConfig, provide if (!provider.isHealthy) { provider.isHealthy = true; provider.errorCount = 0; + provider.refreshCount = 0; provider.lastErrorTime = null; resetCount++; } diff --git a/src/ui-modules/usage-api.js b/src/ui-modules/usage-api.js index de7d25e..b7f73ec 100644 --- a/src/ui-modules/usage-api.js +++ b/src/ui-modules/usage-api.js @@ -184,6 +184,10 @@ function getProviderDisplayName(provider, providerType) { return provider.customName; } + if (provider.uuid) { + return provider.uuid; + } + // 尝试从凭据文件路径提取名称 const credPathKey = { 'claude-kiro-oauth': 'KIRO_OAUTH_CREDS_FILE_PATH', @@ -200,7 +204,7 @@ function getProviderDisplayName(provider, providerType) { return `${dirName}/${fileName}`; } - return provider.uuid || 'Unnamed'; + return 'Unnamed'; } /** diff --git a/static/components/section-dashboard.css b/static/components/section-dashboard.css index 0bd25ce..8edc749 100644 --- a/static/components/section-dashboard.css +++ b/static/components/section-dashboard.css @@ -355,6 +355,364 @@ } } +/* ======================================== + 可用模型列表样式 + ======================================== */ + +.models-section { + margin-top: 2rem; + padding-top: 1.5rem; + border-top: 1px solid var(--border-color); +} + +.models-section-title { + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 1.25rem; + color: var(--text-primary); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.models-section-title i { + color: var(--primary-color); +} + +/* 模型描述区域 */ +.models-description { + margin-bottom: 1.5rem; +} + +/* 模型容器 */ +.models-container { + background: var(--bg-secondary); + padding: 1.25rem; + border-radius: var(--radius-lg); + border: 1px solid var(--border-color); +} + +.models-list { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +/* 加载状态 */ +.models-loading { + display: flex; + align-items: center; + justify-content: center; + gap: 0.75rem; + padding: 2.5rem; + color: var(--text-secondary); + font-size: 1rem; +} + +.models-loading i { + font-size: 1.25rem; + color: var(--primary-color); +} + +/* 提供商模型组 */ +.provider-models-group { + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; + transition: var(--transition); + background: var(--bg-primary); +} + +.provider-models-group:hover { + border-color: var(--primary-color); + box-shadow: var(--shadow-md); +} + +/* 提供商标题 */ +.provider-models-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.875rem 1.25rem; + background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%); + border-bottom: 1px solid var(--border-color); + cursor: pointer; + transition: var(--transition); +} + +.provider-models-header:hover { + background: linear-gradient(135deg, var(--primary-10) 0%, var(--bg-tertiary) 100%); +} + +.provider-models-title { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.provider-models-title i { + font-size: 1.125rem; + color: var(--primary-color); +} + +.provider-models-title h3 { + margin: 0; + font-size: 1rem; + font-weight: 600; + color: var(--text-primary); +} + +.provider-models-count { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 1.5rem; + height: 1.5rem; + padding: 0 0.4rem; + background: var(--primary-color); + color: white; + border-radius: 9999px; + font-size: 0.7rem; + font-weight: 600; +} + +.provider-models-toggle { + color: var(--text-secondary); + transition: var(--transition); +} + +.provider-models-header.collapsed .provider-models-toggle { + transform: rotate(-90deg); +} + +/* 模型列表内容 */ +.provider-models-content { + padding: 0.875rem 1.25rem; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 0.625rem; +} + +.provider-models-content.collapsed { + display: none; +} + +/* 单个模型项 */ +.model-item { + display: flex; + align-items: center; + gap: 0.625rem; + padding: 0.625rem 0.875rem; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + cursor: pointer; + transition: var(--transition); + position: relative; + overflow: hidden; +} + +.model-item:hover { + border-color: var(--primary-color); + background: var(--primary-10); + transform: translateY(-2px); + box-shadow: var(--shadow-sm); +} + +.model-item:active { + transform: translateY(0); +} + +.model-item-icon { + display: flex; + align-items: center; + justify-content: center; + width: 1.75rem; + height: 1.75rem; + background: var(--primary-10); + border-radius: var(--radius-sm); + color: var(--primary-color); + flex-shrink: 0; + font-size: 0.75rem; +} + +.model-item-name { + flex: 1; + font-size: 0.8rem; + font-weight: 500; + color: var(--text-primary); + word-break: break-all; +} + +.model-item-copy { + display: flex; + align-items: center; + justify-content: center; + width: 1.25rem; + height: 1.25rem; + color: var(--text-tertiary); + opacity: 0; + transition: var(--transition); + font-size: 0.75rem; +} + +.model-item:hover .model-item-copy { + opacity: 1; + color: var(--primary-color); +} + +/* 复制成功动画 */ +.model-item.copied { + border-color: var(--success-color); + background: var(--success-10); +} + +.model-item.copied .model-item-copy { + opacity: 1; + color: var(--success-color); +} + +.model-item.copied::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: var(--success-color); + opacity: 0.1; + animation: copyFlash 0.3s ease-out; +} + +@keyframes copyFlash { + 0% { + opacity: 0.3; + } + 100% { + opacity: 0; + } +} + +/* 空状态 */ +.models-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 2.5rem; + color: var(--text-secondary); + text-align: center; +} + +.models-empty i { + font-size: 2.5rem; + margin-bottom: 0.75rem; + opacity: 0.5; +} + +.models-empty p { + margin: 0; + font-size: 0.9rem; +} + +/* 高亮说明样式 */ +.models-description .highlight-note { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.875rem 1rem; + background: linear-gradient(135deg, var(--info-bg) 0%, var(--info-bg-light, var(--info-bg)) 100%); + border: 1px solid var(--info-border); + border-radius: 0.5rem; + color: var(--info-text); + font-weight: 500; + width: 100%; + box-sizing: border-box; + font-size: 0.875rem; +} + +.models-description .highlight-note i { + color: var(--info-color, var(--info-text)); + font-size: 1.125rem; + flex-shrink: 0; +} + +.models-description .highlight-note span { + flex: 1; + text-align: center; +} + +@media (max-width: 768px) { + .provider-models-content { + grid-template-columns: 1fr; + } + + .provider-models-header { + padding: 0.75rem 1rem; + } + + .provider-models-title h3 { + font-size: 0.9rem; + } + + .model-item { + padding: 0.5rem 0.75rem; + } +} + +/* 暗黑主题适配 */ +[data-theme="dark"] .stat-card { + background: var(--bg-primary); +} + +[data-theme="dark"] .provider-models-group { + background: var(--bg-primary); + border-color: var(--border-color); +} + +[data-theme="dark"] .provider-models-header { + background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%); +} + +[data-theme="dark"] .provider-models-header:hover { + background: linear-gradient(135deg, var(--primary-10) 0%, var(--bg-tertiary) 100%); +} + +[data-theme="dark"] .model-item { + background: var(--bg-secondary); + border-color: var(--border-color); +} + +[data-theme="dark"] .model-item:hover { + background: var(--primary-10); + border-color: var(--primary-color); +} + +[data-theme="dark"] .models-description .highlight-note { + background: linear-gradient(135deg, var(--info-bg) 0%, var(--info-bg-light, var(--info-bg)) 100%); + border-color: var(--info-border); + color: var(--info-text); +} + +[data-theme="dark"] .models-container { + background: var(--bg-secondary); +} + +@media (max-width: 1024px) { + .dashboard-top-row { + flex-direction: column; + } + + .dashboard-top-row .stats-grid { + flex: none; + } + + .dashboard-top-row .dashboard-contact .qr-code { + width: 160px; + height: 160px; + } +} + @media (max-width: 768px) { .stats-grid { grid-template-columns: 1fr; diff --git a/static/components/section-dashboard.html b/static/components/section-dashboard.html index c791136..dc1eaf2 100644 --- a/static/components/section-dashboard.html +++ b/static/components/section-dashboard.html @@ -612,6 +612,28 @@
  • 跨协议调用: 支持OpenAI协议调用Claude模型,或Claude协议调用OpenAI模型
  • + + +
    +

    可用模型列表

    +
    +
    + + 点击模型名称可直接复制到剪贴板 +
    +
    + + +
    +
    + +
    + + 加载中... +
    +
    +
    +
    \ No newline at end of file diff --git a/static/components/section-guide.css b/static/components/section-guide.css index 68ba39b..c608c71 100644 --- a/static/components/section-guide.css +++ b/static/components/section-guide.css @@ -591,323 +591,3 @@ [data-theme="dark"] .api-example pre { background: var(--bg-tertiary); } - -/* ======================================== - 可用模型列表样式 (从 section-models.css 合并) - ======================================== */ - -/* 模型描述区域 */ -.models-description { - margin-bottom: 1.5rem; -} - -/* 模型容器 */ -.models-container { - background: var(--bg-secondary); - padding: 1.25rem; - border-radius: var(--radius-lg); - border: 1px solid var(--border-color); -} - -.models-list { - display: flex; - flex-direction: column; - gap: 1.25rem; -} - -/* 加载状态 */ -.models-loading { - display: flex; - align-items: center; - justify-content: center; - gap: 0.75rem; - padding: 2.5rem; - color: var(--text-secondary); - font-size: 1rem; -} - -.models-loading i { - font-size: 1.25rem; - color: var(--primary-color); -} - -/* 提供商模型组 */ -.provider-models-group { - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - overflow: hidden; - transition: var(--transition); - background: var(--bg-primary); -} - -.provider-models-group:hover { - border-color: var(--primary-color); - box-shadow: var(--shadow-md); -} - -/* 提供商标题 */ -.provider-models-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.875rem 1.25rem; - background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%); - border-bottom: 1px solid var(--border-color); - cursor: pointer; - transition: var(--transition); -} - -.provider-models-header:hover { - background: linear-gradient(135deg, var(--primary-10) 0%, var(--bg-tertiary) 100%); -} - -.provider-models-title { - display: flex; - align-items: center; - gap: 0.75rem; -} - -.provider-models-title i { - font-size: 1.125rem; - color: var(--primary-color); -} - -.provider-models-title h3 { - margin: 0; - font-size: 1rem; - font-weight: 600; - color: var(--text-primary); -} - -.provider-models-count { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 1.5rem; - height: 1.5rem; - padding: 0 0.4rem; - background: var(--primary-color); - color: white; - border-radius: 9999px; - font-size: 0.7rem; - font-weight: 600; -} - -.provider-models-toggle { - color: var(--text-secondary); - transition: var(--transition); -} - -.provider-models-header.collapsed .provider-models-toggle { - transform: rotate(-90deg); -} - -/* 模型列表内容 */ -.provider-models-content { - padding: 0.875rem 1.25rem; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); - gap: 0.625rem; -} - -.provider-models-content.collapsed { - display: none; -} - -/* 单个模型项 */ -.model-item { - display: flex; - align-items: center; - gap: 0.625rem; - padding: 0.625rem 0.875rem; - background: var(--bg-secondary); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - cursor: pointer; - transition: var(--transition); - position: relative; - overflow: hidden; -} - -.model-item:hover { - border-color: var(--primary-color); - background: var(--primary-10); - transform: translateY(-2px); - box-shadow: var(--shadow-sm); -} - -.model-item:active { - transform: translateY(0); -} - -.model-item-icon { - display: flex; - align-items: center; - justify-content: center; - width: 1.75rem; - height: 1.75rem; - background: var(--primary-10); - border-radius: var(--radius-sm); - color: var(--primary-color); - flex-shrink: 0; - font-size: 0.75rem; -} - -.model-item-name { - flex: 1; - font-size: 0.8rem; - font-weight: 500; - color: var(--text-primary); - word-break: break-all; -} - -.model-item-copy { - display: flex; - align-items: center; - justify-content: center; - width: 1.25rem; - height: 1.25rem; - color: var(--text-tertiary); - opacity: 0; - transition: var(--transition); - font-size: 0.75rem; -} - -.model-item:hover .model-item-copy { - opacity: 1; - color: var(--primary-color); -} - -/* 复制成功动画 */ -.model-item.copied { - border-color: var(--success-color); - background: var(--success-10); -} - -.model-item.copied .model-item-copy { - opacity: 1; - color: var(--success-color); -} - -.model-item.copied::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: var(--success-color); - opacity: 0.1; - animation: copyFlash 0.3s ease-out; -} - -@keyframes copyFlash { - 0% { - opacity: 0.3; - } - 100% { - opacity: 0; - } -} - -/* 空状态 */ -.models-empty { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 2.5rem; - color: var(--text-secondary); - text-align: center; -} - -.models-empty i { - font-size: 2.5rem; - margin-bottom: 0.75rem; - opacity: 0.5; -} - -.models-empty p { - margin: 0; - font-size: 0.9rem; -} - -/* 高亮说明样式 */ -.models-description .highlight-note { - display: inline-flex; - align-items: center; - gap: 0.5rem; - padding: 0.875rem 1rem; - background: linear-gradient(135deg, var(--info-bg) 0%, var(--info-bg-light, var(--info-bg)) 100%); - border: 1px solid var(--info-border); - border-radius: 0.5rem; - color: var(--info-text); - font-weight: 500; - width: 100%; - box-sizing: border-box; - font-size: 0.875rem; -} - -.models-description .highlight-note i { - color: var(--info-color, var(--info-text)); - font-size: 1.125rem; - flex-shrink: 0; -} - -.models-description .highlight-note span { - flex: 1; - text-align: center; -} - -/* 模型列表响应式 */ -@media (max-width: 768px) { - .provider-models-content { - grid-template-columns: 1fr; - } - - .provider-models-header { - padding: 0.75rem 1rem; - } - - .provider-models-title h3 { - font-size: 0.9rem; - } - - .model-item { - padding: 0.5rem 0.75rem; - } -} - -/* 模型列表暗黑主题 */ -[data-theme="dark"] .provider-models-group { - background: var(--bg-primary); - border-color: var(--border-color); -} - -[data-theme="dark"] .provider-models-header { - background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%); -} - -[data-theme="dark"] .provider-models-header:hover { - background: linear-gradient(135deg, var(--primary-10) 0%, var(--bg-tertiary) 100%); -} - -[data-theme="dark"] .model-item { - background: var(--bg-secondary); - border-color: var(--border-color); -} - -[data-theme="dark"] .model-item:hover { - background: var(--primary-10); - border-color: var(--primary-color); -} - -[data-theme="dark"] .models-description .highlight-note { - background: linear-gradient(135deg, var(--info-bg) 0%, var(--info-bg-light, var(--info-bg)) 100%); - border-color: var(--info-border); - color: var(--info-text); -} - -[data-theme="dark"] .models-container { - background: var(--bg-secondary); -} \ No newline at end of file diff --git a/static/components/section-guide.html b/static/components/section-guide.html index 99399be..8a66c84 100644 --- a/static/components/section-guide.html +++ b/static/components/section-guide.html @@ -191,30 +191,6 @@ - -
    -

    可用模型列表

    -
    -
    -
    - - 点击模型名称可直接复制到剪贴板 -
    -
    - - -
    -
    - -
    - - 加载中... -
    -
    -
    -
    -
    -

    常见问题