diff --git a/src/popup/transfer.ts b/src/popup/transfer.ts index ddbd0f7..31b3931 100644 --- a/src/popup/transfer.ts +++ b/src/popup/transfer.ts @@ -135,7 +135,22 @@ export function initTransfer(ctx: PopupCtx) { const { environments: existingEnvs, activeEnvId } = await loadEnvironments(); - // 分支 A:导入 v3 环境结构 —— 按"环境名"匹配,已存在的环境跳过,新的环境整批导入 + // 公共:构造一条 DomainConfig,允许 username/password 为空 + const makeConfig = (cfg: any): DomainConfig => ({ + id: cfg.id || genCfgId(), + domain: cfg.domain, + alias: cfg.alias || null, + username: cfg.username || "", + password: cfg.password || "", + autoSubmit: cfg.autoSubmit !== false, + usernameSelector: cfg.usernameSelector || null, + passwordSelector: cfg.passwordSelector || null, + submitSelector: cfg.submitSelector || null, + enabled: cfg.enabled !== false, + delayMs: cfg.delayMs || null, + }); + + // 分支 A:导入 v3 环境结构 —— 同名环境合并配置(按 domain 去重),新环境创建 if (incomingEnvironments) { const existingNames = new Set(existingEnvs.map((e) => e.name)); let addedEnvs = 0; @@ -146,39 +161,31 @@ export function initTransfer(ctx: PopupCtx) { skippedCfgs += env?.configs?.length || 0; continue; } + let targetEnv: Environment; if (existingNames.has(env.name)) { - // 同名环境:跳过整个环境 - skippedCfgs += env.configs?.length || 0; - continue; + // 同名环境:合并配置到现有环境 + targetEnv = existingEnvs.find((e) => e.name === env.name)!; + } else { + // 新环境:创建后再合并 + existingNames.add(env.name); + targetEnv = { id: genId(), name: env.name, configs: [] }; + existingEnvs.push(targetEnv); + addedEnvs++; } - existingNames.add(env.name); - const newEnv: Environment = { - id: genId(), - name: env.name, - configs: [], - }; + const seenDomains = new Set(targetEnv.configs.map((c) => c.domain)); for (const cfg of env.configs || []) { - if (!cfg || !cfg.domain || !cfg.username || !cfg.password) { + if (!cfg?.domain) { skippedCfgs++; continue; } - newEnv.configs.push({ - id: cfg.id || genCfgId(), - domain: cfg.domain, - alias: cfg.alias || null, - username: cfg.username, - password: cfg.password, - autoSubmit: cfg.autoSubmit !== false, - usernameSelector: cfg.usernameSelector || null, - passwordSelector: cfg.passwordSelector || null, - submitSelector: cfg.submitSelector || null, - enabled: cfg.enabled !== false, - delayMs: cfg.delayMs || null, - }); + if (seenDomains.has(cfg.domain)) { + skippedCfgs++; + continue; + } + seenDomains.add(cfg.domain); + targetEnv.configs.push(makeConfig(cfg)); addedCfgs++; } - existingEnvs.push(newEnv); - addedEnvs++; } await saveEnvironments(existingEnvs, activeEnvId ?? undefined); await ctx.renderEnvSelect(); @@ -188,12 +195,17 @@ export function initTransfer(ctx: PopupCtx) { } // 分支 B:导入 v1/v2 配置数组 —— 合并到当前激活环境,相同 domain 跳过 - const curEnv = existingEnvs.find((e) => e.id === activeEnvId) || existingEnvs[0]; + let curEnv = existingEnvs.find((e) => e.id === activeEnvId) || existingEnvs[0]; + if (!curEnv) { + // 无任何环境时先创建一个,否则没有地方放配置 + curEnv = { id: genId(), name: "默认", configs: [] }; + existingEnvs.push(curEnv); + } const seenDomains = new Set(curEnv.configs.map((c) => c.domain)); let added = 0; let skipped = 0; for (const cfg of incomingConfigs || []) { - if (!cfg || !cfg.domain || !cfg.username || !cfg.password) { + if (!cfg?.domain) { skipped++; continue; } @@ -202,19 +214,7 @@ export function initTransfer(ctx: PopupCtx) { continue; } seenDomains.add(cfg.domain); - curEnv.configs.push({ - id: cfg.id || genCfgId(), - domain: cfg.domain, - alias: cfg.alias || null, - username: cfg.username, - password: cfg.password, - autoSubmit: cfg.autoSubmit !== false, - usernameSelector: cfg.usernameSelector || null, - passwordSelector: cfg.passwordSelector || null, - submitSelector: cfg.submitSelector || null, - enabled: cfg.enabled !== false, - delayMs: cfg.delayMs || null, - }); + curEnv.configs.push(makeConfig(cfg)); added++; } await saveEnvironments(existingEnvs);