feat(welcome): show first-run welcome dialog on fresh install

Introduce a one-time welcome dialog that explains CC Switch's workflow
to new users: how their existing config is preserved as a "default"
provider and how the bundled "Official" preset enables one-click revert.
Upgrade users are excluded by checking is_providers_empty() at startup
and never see the dialog.

Persistence follows the existing *_confirmed convention in AppSettings
(proxy/usage/stream_check/failover), stored in settings.json. The field
is only written when the user explicitly clicks the confirm button,
keeping its semantics strictly about user acknowledgement.

Also adds two reusable DAO helpers:
- Database::is_providers_empty for fresh-install detection, using
  EXISTS(SELECT 1) for a short-circuit query.
- Database::get_bool_flag accepting "true" | "1", with
  init_default_official_providers migrated to use it.

Dialog copy in zh/en/ja uses conditional phrasing so it stays
accurate whether or not existing live config was found.
This commit is contained in:
Jason
2026-04-09 13:21:50 +08:00
parent a058ebeafc
commit 8669879ad0
10 changed files with 139 additions and 5 deletions
+15
View File
@@ -472,6 +472,15 @@ pub fn run() {
// 先 import 后 seed 是有意为之:先把用户手动配置的 settings.json / auth.json / .env
// 落成 "default" provider 设为 current,再追加官方预设(is_current=false)。
// 这样用户切到官方预设时,回填机制会保护原 live 配置不丢失。
//
// 捕获首次运行快照:所有全新装用户都会看到欢迎弹窗介绍 CC Switch 的工作方式。
// 读失败时默认不弹,宁可漏弹也不要因为故障打扰用户。
let first_run_already_confirmed = crate::settings::get_settings()
.first_run_notice_confirmed
.unwrap_or(false);
let fresh_install_at_startup =
app_state.db.is_providers_empty().unwrap_or(false);
for app_type in
crate::app_config::AppType::all().filter(|t| !t.is_additive_mode())
{
@@ -502,6 +511,12 @@ pub fn run() {
Err(e) => log::warn!("✗ Failed to seed official providers: {e}"),
}
// 老用户 / 已确认的路径由 `fresh_install_at_startup` 自行拦截,这里不做写入。
// 字段只由前端在用户点击"我知道了"时 save_settings 回写,语义是"用户显式确认过"。
if !first_run_already_confirmed && fresh_install_at_startup {
log::info!("✓ First-run welcome notice pending");
}
// 1.6. 自动同步 OpenCode / OpenClaw 的 live providers 到数据库
//
// additive 模式(OpenCode / OpenClaw)的 import 函数本身按 id 幂等,