mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-07-13 00:11:52 +08:00
feat(channels): 模型配置入口收口到模型渠道页,渠道卡片强化绑定状态
模型配置此前散落三处、口径不一。本次把模型渠道页确立为配置中枢: - OpenClaw 模型配置页顶部新增引导条:推荐在模型渠道统一维护并同步 - Hermes 安装向导配置步新增引导:已有渠道可从渠道页一键同步到 Hermes - 晴辰助手 API 设置新增引导:已有渠道可直接同步到助手,无需重复填写 - 渠道卡片同步区新增「绑定状态」标题,OpenClaw / Hermes / 助手三行 绑定关系(已同步 / 有未同步变更 / 未同步 / 不支持)一目了然 i18n:models / assistant / engine / modelChannels 四个模块补充 简中 / 繁中 / 英文案。验证:npm build + node --test 427 通过。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,9 +16,12 @@
|
||||
- **安装向导断点续行** — 中途关闭面板后重新进入,会回到上次进行到的步骤(以实际检测结果为准),不必从头再走
|
||||
- **配置步骤错误内联展示** — API Key / 配置保存错误改为页面内醒目提示(原为一闪而过的 toast),并提示可用「获取模型列表」验证 Key
|
||||
|
||||
- **模型配置入口统一** — OpenClaw 模型配置页、Hermes 安装向导配置步、晴辰助手 API 设置均新增「前往模型渠道」引导入口,模型接入配置收口到模型渠道页统一维护;渠道卡片新增「绑定状态」标题,与 OpenClaw / Hermes / 助手的同步绑定关系一目了然
|
||||
|
||||
### 修复 (Fixes)
|
||||
|
||||
- **模型渠道 API 类型下拉显示异常** — 修复选项显示为 [object Object] 的问题,改为可读的类型名称
|
||||
- **未安装时不再反复跳回检测页** — 安装/升级失败事件不再把用户从诊断等页面强行拉回初始设置页;窗口重新聚焦触发的环境重检改为后台静默更新,不再清空已显示的检测结果
|
||||
|
||||
### 新功能 (Features)
|
||||
|
||||
|
||||
@@ -291,7 +291,11 @@ export function render() {
|
||||
return `<div class="card" style="margin-bottom:16px">
|
||||
<div class="card-body" style="padding:24px">
|
||||
<h3 style="margin:0 0 4px;font-size:16px">${t('engine.configTitle')}</h3>
|
||||
<p style="color:var(--text-secondary);margin:0 0 20px;font-size:13px">${t('engine.configDesc')}</p>
|
||||
<p style="color:var(--text-secondary);margin:0 0 12px;font-size:13px">${t('engine.configDesc')}</p>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:20px;padding:8px 12px;background:var(--bg-tertiary);border-radius:var(--radius-md,8px);font-size:12px;color:var(--text-secondary)">
|
||||
<span>${t('engine.configChannelsGuide')}</span>
|
||||
<button class="btn btn-sm btn-secondary hermes-goto-channels" type="button" style="white-space:nowrap;flex-shrink:0">${t('engine.configChannelsGuideBtn')}</button>
|
||||
</div>
|
||||
|
||||
<div class="hermes-form">
|
||||
<div class="hermes-field">
|
||||
@@ -447,6 +451,10 @@ export function render() {
|
||||
const dd = el.querySelector('#hm-model-dropdown')
|
||||
if (dd && !e.target.closest('.hermes-field')) dd.style.display = 'none'
|
||||
})
|
||||
// 前往模型渠道页(可在渠道页统一维护后同步回 Hermes)
|
||||
el.querySelector('.hermes-goto-channels')?.addEventListener('click', () => {
|
||||
window.location.hash = '#/model-channels'
|
||||
})
|
||||
// 配置保存
|
||||
el.querySelector('.hermes-config-save')?.addEventListener('click', doSaveConfig)
|
||||
el.querySelector('.hermes-config-skip')?.addEventListener('click', () => { phase = 'gateway'; refreshHermes() })
|
||||
|
||||
@@ -286,6 +286,8 @@ export default {
|
||||
model: _('模型', 'Model', '', 'モデル', '모델', 'Mô hình', 'Modelo', 'Modelo', 'Модель', 'Modèle', 'Modell'),
|
||||
temperature: _('温度', 'Temperature', '溫度', '温度', '온도', 'Nhiệt độ', 'Temperatura', 'Temperatura', 'Температура', 'Température', 'Temperatur'),
|
||||
quickSelect: _('快捷选择', 'Quick Select', '快捷選擇', 'クイック選択', '빠른 선택'),
|
||||
channelsGuide: _('已在「模型渠道」维护过接入配置?可直接同步到助手,无需重复填写', 'Already set up on the Model Channels page? Sync it to the assistant instead of re-typing', '已在「模型渠道」維護過接入設定?可直接同步到助手,無需重複填寫'),
|
||||
channelsGuideBtn: _('前往模型渠道', 'Open Model Channels', '前往模型渠道'),
|
||||
visitSite: _('访问官网', 'Visit Website', '訪問官網', 'サイトを訪問', '사이트 방문'),
|
||||
notConfigured: _('未配置', 'Not configured', '未設定', '未設定', '미설정'),
|
||||
qtcoolName: _('晴辰云', 'QingChen Cloud', '晴辰雲'),
|
||||
|
||||
@@ -111,6 +111,8 @@ export default {
|
||||
installGitMirror: _('Git 镜像前缀(可选)', 'Git mirror prefix (optional)', 'Git 鏡像前綴(可選)'),
|
||||
installNetworkHint: _('依赖下载失败或速度慢时,选择国内镜像后重试。设置会保存,下次安装/升级自动生效。', 'If dependency downloads fail or crawl, pick a mirror and retry. The setting is saved and reused for future installs/upgrades.', '依賴下載失敗或速度慢時,選擇鏡像後重試。設定會儲存,下次安裝/升級自動生效。'),
|
||||
configKeyVerifyHint: _('提示:点「获取模型列表」可顺便验证 Key 是否有效', 'Tip: "Fetch models" also verifies that your key works', '提示:點「獲取模型清單」可順便驗證 Key 是否有效'),
|
||||
configChannelsGuide: _('已在「模型渠道」维护过接入配置?可从渠道页一键同步到 Hermes,无需重复填写', 'Already set up on the Model Channels page? Sync it to Hermes from there instead of re-typing', '已在「模型渠道」維護過接入設定?可從渠道頁一鍵同步到 Hermes,無需重複填寫'),
|
||||
configChannelsGuideBtn: _('前往模型渠道', 'Open Model Channels', '前往模型渠道'),
|
||||
configApiKeyRequired: _('请输入 API Key', 'Please enter an API key', '請輸入 API Key'),
|
||||
configSaveFailed: _('配置保存失败', 'Failed to save configuration', '設定儲存失敗'),
|
||||
installModeLocal: _('本地', 'Local', '本地'),
|
||||
|
||||
@@ -42,6 +42,7 @@ export default {
|
||||
nameRequired: _('请填写渠道名称', 'Channel name is required', '請填寫渠道名稱'),
|
||||
baseUrlRequired: _('请填写以 http:// 或 https:// 开头的接口地址', 'Base URL must start with http:// or https://', '請填寫以 http:// 或 https:// 開頭的介面位址'),
|
||||
modelCount: _('{count} 个模型', '{count} models', '{count} 個模型'),
|
||||
bindings: _('绑定状态', 'Bindings', '綁定狀態'),
|
||||
syncOpenclaw: _('同步到 OpenClaw', 'Sync to OpenClaw', '同步到 OpenClaw'),
|
||||
syncHermes: _('同步到 Hermes', 'Sync to Hermes', '同步到 Hermes'),
|
||||
syncAssistant: _('同步到助手', 'Sync to Assistant', '同步到助手'),
|
||||
|
||||
@@ -23,6 +23,8 @@ export default {
|
||||
undoN: _('↩ 撤销 ({n})', '↩ Undo ({n})'),
|
||||
undone: _('已撤销', 'Undone'),
|
||||
providerHint: _('服务商是模型的来源(如 OpenAI、DeepSeek 等)。每个服务商下可添加多个模型。标记为「主模型」的将优先使用,其余作为备选自动切换。配置修改后自动保存。', 'Providers are sources of models (e.g. OpenAI, DeepSeek). Each provider can have multiple models. The "primary" model is used first; others serve as fallbacks. Changes are auto-saved.', '服務商是模型的來源(如 OpenAI、DeepSeek 等)。每個服務商下可新增多個模型。標記為「主模型」的將優先使用,其餘作為備選自動切換。設定修改后自動儲存。'),
|
||||
channelsGuide: _('推荐在「模型渠道」页统一维护接入配置(地址、密钥、模型),可一键同步到 OpenClaw、Hermes 与晴辰助手', 'Tip: maintain provider access (URL, key, models) once on the Model Channels page and sync it to OpenClaw, Hermes, and the assistant', '推薦在「模型渠道」頁統一維護接入設定(位址、金鑰、模型),可一鍵同步到 OpenClaw、Hermes 與晴辰助手'),
|
||||
channelsGuideBtn: _('前往模型渠道', 'Open Model Channels', '前往模型渠道'),
|
||||
qtcoolName: _('晴辰云', 'QingChen Cloud', '晴辰雲'),
|
||||
qtcoolRecommend: _('推荐', 'Recommended', '推薦'),
|
||||
qtcoolDesc: _('每日签到领取免费模型测试额度,邀请好友再送额度。付费低至官方价 2-3 折,不满意随时可退。', 'Daily check-in for free model credits, invite friends for bonus. Paid plans as low as 20-30% of official price. Refund anytime.', '每日簽到領取免費模型測試額度,邀請好友再送額度。付費低至官方價 2-3 折,不滿意隨時可退。', '毎日チェックインで無料クレジット獲得、友達招待でボーナス。有料は公式価格の2〜3割', '매일 체크인으로 무료 크레딧, 친구 초대 보너스. 유료는 공식가의 2~3할'),
|
||||
|
||||
@@ -4089,6 +4089,10 @@ function showSettings() {
|
||||
<div class="modal-body">
|
||||
<div class="ast-settings-form">
|
||||
<div class="ast-tab-panel active" data-panel="api">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px;padding:8px 12px;background:var(--bg-tertiary);border-radius:var(--radius-md);font-size:12px;color:var(--text-secondary)">
|
||||
<span>${t('assistant.channelsGuide')}</span>
|
||||
<button class="btn btn-sm btn-secondary ast-goto-channels" type="button" style="white-space:nowrap;flex-shrink:0">${t('assistant.channelsGuideBtn')}</button>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom:8px">
|
||||
<label class="form-label">${t('assistant.quickSelect')}</label>
|
||||
<div id="ast-provider-presets" style="display:flex;flex-wrap:wrap;gap:6px">
|
||||
@@ -4555,6 +4559,12 @@ function showSettings() {
|
||||
})
|
||||
})
|
||||
|
||||
// 前往模型渠道页(统一维护接入配置的中枢入口)
|
||||
overlay.querySelector('.ast-goto-channels')?.addEventListener('click', () => {
|
||||
overlay.remove()
|
||||
window.location.hash = '#/model-channels'
|
||||
})
|
||||
|
||||
// 服务商快捷预设按钮
|
||||
const apiTypeSelect = overlay.querySelector('#ast-apitype')
|
||||
const apiHintEl = overlay.querySelector('#ast-api-hint')
|
||||
|
||||
@@ -187,6 +187,7 @@ function renderChannelCard(state, channel) {
|
||||
${channel.defaultModel ? `<span class="mch-chip">${icon('check', 11)} ${esc(channel.defaultModel)}</span>` : ''}
|
||||
</div>
|
||||
<div class="mch-sync-row">
|
||||
<div style="font-size:11px;font-weight:600;color:var(--text-tertiary);letter-spacing:0.3px">${t('modelChannels.bindings')}</div>
|
||||
${renderSyncLine(state, channel, 'openclaw', t('modelChannels.targetOpenclaw'), true, '', t('modelChannels.syncOpenclaw'))}
|
||||
${renderSyncLine(state, channel, 'hermes', t('modelChannels.targetHermes'), hermesSyncSupported(channel), t('modelChannels.syncHermesUnsupported'), t('modelChannels.syncHermes'))}
|
||||
${renderSyncLine(state, channel, 'assistant', t('modelChannels.targetAssistant'), assistantSyncSupported(channel), t('modelChannels.syncAssistantUnsupported'), t('modelChannels.syncAssistant'))}
|
||||
|
||||
@@ -35,6 +35,10 @@ export async function render() {
|
||||
<div class="form-hint" style="margin-bottom:var(--space-md)">
|
||||
${t('models.providerHint')}
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:var(--space-md);padding:10px 14px;background:var(--bg-secondary);border:1px solid var(--border-primary);border-left:3px solid var(--primary);border-radius:var(--radius-md);font-size:var(--font-size-sm);color:var(--text-secondary)">
|
||||
<span>${t('models.channelsGuide')}</span>
|
||||
<button class="btn btn-sm btn-secondary" id="btn-goto-channels" type="button" style="white-space:nowrap;flex-shrink:0">${t('models.channelsGuideBtn')}</button>
|
||||
</div>
|
||||
<div id="qtcool-promo" style="margin-bottom:var(--space-md);border-radius:var(--radius-lg);border:1px solid var(--border-primary);border-left:3px solid var(--primary);background:var(--bg-secondary);padding:16px 20px">
|
||||
<div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:12px;margin-bottom:12px">
|
||||
<div style="flex:1;min-width:200px">
|
||||
@@ -1168,6 +1172,8 @@ function applyDefaultModel(state) {
|
||||
function bindTopActions(page, state) {
|
||||
page.querySelector('#btn-add-provider').onclick = () => addProvider(page, state)
|
||||
page.querySelector('#btn-import-client').onclick = () => importClientConfigs(page, state)
|
||||
const gotoChannels = page.querySelector('#btn-goto-channels')
|
||||
if (gotoChannels) gotoChannels.onclick = () => { window.location.hash = '#/model-channels' }
|
||||
page.querySelector('#btn-undo').onclick = () => undo(page, state)
|
||||
|
||||
// 晴辰云:获取模型列表 → 弹窗让用户选择要添加的模型
|
||||
|
||||
Reference in New Issue
Block a user