fix: 插件版本 pin 策略修正 + i18n key 补全

- channels.js: 仅对 @openclaw/ 前缀包做版本 pin(飞书等),微信/QQ 独立版本号不 pin
- dashboard.js locale: 新增 guardianFailed/autoFix/fixing 等 15 个修复弹窗 i18n key
- channels.js locale: 新增 pluginIncompatible/reinstallCompatible i18n key
- main.js: Guardian 恢复 banner 改为 t() 国际化调用
This commit is contained in:
晴天
2026-03-26 03:50:24 +08:00
parent 1d0586dd39
commit 112394bf08
4 changed files with 30 additions and 19 deletions

View File

@@ -304,4 +304,6 @@ export default {
pluginDetected: _('已检测到插件,无需重复安装,本次仅更新配置', 'Plugin detected, no need to reinstall; only updating config', '已檢測到外掛,無需重複安裝,本次僅更新設定'),
writingConfig: _('写入配置...', 'Writing config...', '写入設定...'),
configSaved: _('{platform} 配置已保存Gateway 正在重载', '{platform} config saved, Gateway is reloading', '{platform} 設定已儲存Gateway 正在重載'),
pluginIncompatible: _('插件版本不兼容', 'Plugin version incompatible', '外掛版本不相容', 'プラグインバージョン非互換', '플러그인 버전 호환되지 않음', 'Phiên bản plugin không tương thích', 'Versión de plugin incompatible', 'Versão do plugin incompatível', 'Несовместимая версия плагина', 'Version de plugin incompatible', 'Plugin-Version inkompatibel'),
reinstallCompatible: _('重新安装兼容版本', 'Reinstall compatible version', '重新安裝相容版本', '互換バージョンを再インストール', '호환 버전 재설치', 'Cài đặt lại phiên bản tương thích', 'Reinstalar versión compatible', 'Reinstalar versão compatível', 'Переустановить совместимую версию', 'Réinstaller la version compatible', 'Kompatible Version neu installieren'),
}

View File

@@ -80,4 +80,18 @@ export default {
backingUp: _('备份中...', 'Backing up...', '備份中...', 'バックアップ中...', '백업 중...', 'Đang sao lưu...', 'Respaldando...', 'Fazendo backup...', 'Резервное копирование...', 'Sauvegarde...', 'Backup wird erstellt...'),
backupDone: _('已备份: {name}', 'Backed up: {name}', '已備份: {name}', 'バックアップ完了: {name}', '백업 완료: {name}'),
backupFail: _('备份失败', 'Backup failed', '備份失敗', 'バックアップ失敗', '백업 실패', 'Sao lưu thất bại', 'Respaldo fallido', 'Falha no backup', 'Ошибка резервного копирования', 'Échec de la sauvegarde', 'Backup fehlgeschlagen'),
guardianFailed: _('Gateway 反复启动失败,可能配置有误', 'Gateway failed to start repeatedly, config may be incorrect', 'Gateway 反覆啟動失敗,可能設定有誤', 'Gateway の起動が繰り返し失敗しました。設定が正しくない可能性があります', 'Gateway가 반복적으로 시작에 실패했습니다. 설정이 잘못되었을 수 있습니다'),
autoFix: _('一键修复', 'Auto Fix', '一鍵修復', '自動修復', '자동 수정', 'Tự động sửa', 'Reparación automática', 'Correção automática', 'Автоисправление', 'Réparation auto', 'Automatische Reparatur'),
fixing: _('修复中...', 'Fixing...', '修復中...', '修復中...', '수정 중...'),
retryStart: _('重试启动', 'Retry Start', '重試啟動', '再起動', '재시작'),
fixModalTitle: _('🔧 自动修复', '🔧 Auto Fix', '🔧 自動修復', '🔧 自動修復', '🔧 자동 수정'),
fixModalDesc: _('正在执行 openclaw doctor --fix自动检测并修复常见配置问题...', 'Running openclaw doctor --fix to auto-detect and fix common config issues...', '正在執行 openclaw doctor --fix自動檢測並修復常見設定問題...', 'openclaw doctor --fix を実行して一般的な設定問題を自動修復中...', 'openclaw doctor --fix 를 실행하여 일반적인 구성 문제를 자동 수정 중...'),
fixRunning: _('⏳ 执行中...', '⏳ Running...', '⏳ 執行中...', '⏳ 実行中...', '⏳ 실행 중...'),
fixDoneNoOutput: _('✅ 修复完成(无输出)', '✅ Fix completed (no output)', '✅ 修復完成(無輸出)', '✅ 修復完了(出力なし)', '✅ 수정 완료 (출력 없음)'),
fixDoneWarning: _('⚠ 修复完成,但有警告:', '⚠ Fix completed with warnings:', '⚠ 修復完成,但有警告:', '⚠ 修復完了(警告あり):', '⚠ 수정 완료, 경고 있음:'),
fixDoneRestarting: _('✅ 修复完成,正在重启 Gateway...', '✅ Fix completed, restarting Gateway...', '✅ 修復完成,正在重啟 Gateway...', '✅ 修復完了、Gateway を再起動中...', '✅ 수정 완료, Gateway 재시작 중...'),
fixDoneRestarted: _('✅ 修复完成Gateway 已重启', '✅ Fix completed, Gateway restarted', '✅ 修復完成Gateway 已重啟', '✅ 修復完了、Gateway 再起動済み', '✅ 수정 완료, Gateway 재시작됨'),
fixDoneRestartFail: _('✅ 修复完成,但 Gateway 启动失败,请手动检查', '✅ Fix completed, but Gateway failed to start. Please check manually', '✅ 修復完成,但 Gateway 啟動失敗,請手動檢查', '✅ 修復完了、しかし Gateway の起動に失敗。手動で確認してください', '✅ 수정 완료, 그러나 Gateway 시작 실패. 수동으로 확인하세요'),
fixFailed: _('❌ 修复失败:', '❌ Fix failed:', '❌ 修復失敗:', '❌ 修復失敗:', '❌ 수정 실패:'),
startSent: _('已发送启动命令', 'Start command sent', '已發送啟動指令', '起動コマンド送信済み', '시작 명령 전송됨'),
}

View File

@@ -598,10 +598,10 @@ function showGuardianRecovery() {
banner.innerHTML = `
<div class="gw-banner-content" style="flex-wrap:wrap;gap:8px">
<span class="gw-banner-icon">${statusIcon('warn', 16)}</span>
<span>Gateway 反复启动失败,可能配置有误</span>
<button class="btn btn-sm btn-primary" id="btn-gw-recover-fix" style="margin-left:auto">一键修复</button>
<button class="btn btn-sm btn-secondary" id="btn-gw-recover-restart">重试启动</button>
<a class="btn btn-sm btn-ghost" href="#/logs">查看日志</a>
<span>${t('dashboard.guardianFailed')}</span>
<button class="btn btn-sm btn-primary" id="btn-gw-recover-fix" style="margin-left:auto">${t('dashboard.autoFix')}</button>
<button class="btn btn-sm btn-secondary" id="btn-gw-recover-restart">${t('dashboard.retryStart')}</button>
<a class="btn btn-sm btn-ghost" href="#/logs">${t('sidebar.logs')}</a>
</div>
`
banner.querySelector('#btn-gw-recover-fix')?.addEventListener('click', async (e) => {

View File

@@ -1788,15 +1788,8 @@ async function openConfigDialog(pid, page, state, accountId) {
}
})
// 自动 pin 插件版本(仅 install 动作)
let actionVer2 = null
if (actionId === 'install') {
try {
const vInfo = await api.getVersionInfo()
if (vInfo?.current) actionVer2 = vInfo.current.split('-')[0]
} catch {}
}
const output = await api.runChannelAction(pid, actionId, actionVer2)
// 微信/QQ 等第三方插件版本号独立,不 pinrun_channel_action 的 version 参数仅用于 npx 包名
const output = await api.runChannelAction(pid, actionId, null)
toast(t('channels.actionDone'), 'success')
if (logBox && output && !String(output).includes(logBox.textContent)) {
logBox.textContent += (logBox.textContent ? '\n' : '') + String(output)
@@ -1954,15 +1947,17 @@ async function openConfigDialog(pid, page, state, accountId) {
} catch {}
try {
// 自动 pin 插件版本到用户的 OpenClaw 版本,避免 minHostVersion 不兼容
// 自动 pin 插件版本:仅 @openclaw/ 前缀的包与 OpenClaw 版本号同步,其他包(微信 CLI、QQ Bot版本号独立
let pluginVersion = null
try {
const vInfo = await api.getVersionInfo()
if (vInfo?.current) pluginVersion = vInfo.current.split('-')[0]
} catch {}
if (pluginPackage && pluginPackage.startsWith('@openclaw/')) {
try {
const vInfo = await api.getVersionInfo()
if (vInfo?.current) pluginVersion = vInfo.current.split('-')[0]
} catch {}
}
// QQ 必须用专用安装命令:官方包目录为 openclaw-qqbot与 install_channel_plugin(…, "qqbot") 的备份路径不一致
if (pid === 'qqbot') {
await api.installQqbotPlugin(pluginVersion)
await api.installQqbotPlugin(null)
} else {
await api.installChannelPlugin(pluginPackage, pluginId, pluginVersion)
}