feat(ui): 全局弹窗替代原生 alert/confirm,添加防重复提交与搜索功能
- 新增 ConfirmModal / ResultModal 全局组件,替代原生 alert/confirm/prompt - 资产/平台/账号保存添加防重复提交锁(assetSaving / providerSaving) - 添加 Esc 键盘快捷键关闭模态框 - 平台/监控视图添加搜索过滤功能 - 修复监控中心 SSL TAB 下新增按钮的显示逻辑 - 调整 toast 位置避免遮挡底部导航 - 统一各弹窗 z-index 层级
This commit is contained in:
@@ -141,26 +141,26 @@ const AssetsView = {
|
||||
return p ? p.name : slug;
|
||||
}
|
||||
async function refreshBalance(a) {
|
||||
if (!confirm('刷新「' + a.name + '」的余额?')) return;
|
||||
if (!await showConfirm('刷新余额', '刷新「' + a.name + '」的余额?')) return;
|
||||
try {
|
||||
const r = await Api.post('/assets/' + a.id + '/refresh-balance', {});
|
||||
alert('余额已更新:' + r.balance + ' ' + r.currency);
|
||||
showResult('刷新成功', '余额已更新:' + r.balance + ' ' + r.currency);
|
||||
await loadAssets();
|
||||
} catch (e) { alert('刷新失败:' + e.message); }
|
||||
} catch (e) { showResult('刷新失败', e.message, true); }
|
||||
}
|
||||
async function syncAllAI() {
|
||||
if (!confirm('同步所有 AI 账号的余额?')) return;
|
||||
if (!await showConfirm('同步 AI 余额', '同步所有 AI 账号的余额?')) return;
|
||||
try {
|
||||
const r = await Api.post('/sync/ai-balances', {});
|
||||
// skipped:平台本身没余额接口(如 OpenAI 已下线 billing),不属于失败
|
||||
alert('同步完成:成功 ' + r.success + ',失败 ' + r.failed +
|
||||
showResult('同步完成', '成功 ' + r.success + ',失败 ' + r.failed +
|
||||
(r.skipped ? ',跳过 ' + r.skipped + '(平台无余额接口)' : '') +
|
||||
(r.errors && r.errors.length ? '\n' + r.errors.join('\n') : ''));
|
||||
await loadAssets();
|
||||
} catch (e) { alert('同步失败:' + e.message); }
|
||||
} catch (e) { showResult('同步失败', e.message, true); }
|
||||
}
|
||||
async function syncAllAssets() {
|
||||
if (!confirm('从云端拉取所有已配 API 凭证账号下的 VPS 与域名?\n\n会按 (平台, 云端实例ID) 去重:已存在则更新状态/到期日,不存在则新建。')) return;
|
||||
if (!await showConfirm('同步云端资产', '从云端拉取所有已配 API 凭证账号下的 VPS 与域名?\n\n会按 (平台, 云端实例ID) 去重:已存在则更新状态/到期日,不存在则新建。')) return;
|
||||
try {
|
||||
const r = await Api.post('/sync/assets', {});
|
||||
const lines = [
|
||||
@@ -172,9 +172,9 @@ const AssetsView = {
|
||||
if (r.skipped_no_config) lines.push('跳过(账号未配 API 凭证):' + r.skipped_no_config);
|
||||
if (r.skipped_no_adapter) lines.push('跳过(平台无可用适配器):' + r.skipped_no_adapter);
|
||||
if (r.errors && r.errors.length) lines.push('\n' + r.errors.join('\n'));
|
||||
alert(lines.join('\n'));
|
||||
showResult('同步完成', lines.join('\n'));
|
||||
await Promise.all([loadAssets(), loadOverview()]);
|
||||
} catch (e) { alert('同步失败:' + e.message); }
|
||||
} catch (e) { showResult('同步失败', e.message, true); }
|
||||
}
|
||||
return { store, Fmt, tabs, tabView, list, switchTab, providerName, reload: loadAssets, clearProvider: clearProviderFilter, edit: openAssetEdit, del: deleteAsset, viewServer, refreshBalance, syncAllAI, syncAllAssets, canControl: assetCanControl, openAct: openActions };
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user