Przeglądaj źródła

feat: 更新邮箱记录模块,支持“停止”状态并优化统计摘要,调整测试用例以反映新逻辑

祁连海 4 miesięcy temu
rodzic
commit
a41fde45c8

+ 11 - 3
sidepanel/account-records-manager.js

@@ -39,6 +39,8 @@
           summary.success += 1;
         } else if (record.finalStatus === 'failed') {
           summary.failed += 1;
+        } else if (record.finalStatus === 'stopped') {
+          summary.stopped += 1;
         }
         summary.retryTotal += Math.max(0, Math.floor(Number(record.retryCount) || 0));
         return summary;
@@ -46,6 +48,7 @@
         total: 0,
         success: 0,
         failed: 0,
+        stopped: 0,
         retryTotal: 0,
       });
     }
@@ -81,9 +84,13 @@
     }
 
     function getStatusMeta(record = {}) {
-      return record.finalStatus === 'success'
-        ? { kind: 'success', label: '成功' }
-        : { kind: 'failed', label: '失败' };
+      if (record.finalStatus === 'success') {
+        return { kind: 'success', label: '成功' };
+      }
+      if (record.finalStatus === 'stopped') {
+        return { kind: 'stopped', label: '停止' };
+      }
+      return { kind: 'failed', label: '失败' };
     }
 
     function getRecordSummaryText(record = {}) {
@@ -114,6 +121,7 @@
         createStatChip('总', summary.total),
         createStatChip('成', summary.success, 'is-success'),
         createStatChip('失', summary.failed, 'is-failed'),
+        createStatChip('停', summary.stopped, 'is-stopped'),
         createStatChip('重试', summary.retryTotal, 'is-retry'),
       ].join('');
     }

+ 17 - 4
tests/background-account-run-history-module.test.js

@@ -16,7 +16,7 @@ test('account run history module exposes a factory', () => {
   assert.equal(typeof api?.createAccountRunHistoryHelpers, 'function');
 });
 
-test('account run history helper upgrades old records, filters stopped items and stores normalized failed snapshot records', async () => {
+test('account run history helper upgrades old records, keeps stopped items and stores normalized failed snapshot records', async () => {
   const source = fs.readFileSync('background/account-run-history.js', 'utf8');
   const globalScope = {};
   const api = new Function('self', `${source}; return self.MultiPageBackgroundAccountRunHistory;`)(globalScope);
@@ -93,14 +93,25 @@ test('account run history helper upgrades old records, filters stopped items and
   assert.equal(appended.email, 'latest@example.com');
   assert.equal(appended.finalStatus, 'failed');
   assert.equal(appended.failureLabel, '出现手机号验证');
-  assert.equal(storedHistory.length, 2, '旧的 stopped 记录应在新结构中被过滤掉');
-  assert.equal(storedHistory.some((item) => item.email === 'stop@example.com'), false);
+  assert.equal(storedHistory.length, 3, '旧的 stopped 记录应在新结构中保留');
+  assert.equal(storedHistory.some((item) => item.email === 'stop@example.com' && item.finalStatus === 'stopped'), true);
   assert.equal(storedHistory.some((item) => item.email === 'latest@example.com' && item.retryCount === 2), true);
   assert.equal(storedHistory.some((item) => item.email === 'old@example.com'), true);
   assert.equal(fetchCalled, false);
   assert.equal(helpers.shouldAppendAccountRunTextFile({ accountRunHistoryTextEnabled: false, accountRunHistoryHelperBaseUrl: 'http://127.0.0.1:17373' }), false);
   assert.equal(helpers.shouldAppendAccountRunTextFile({ accountRunHistoryTextEnabled: true, accountRunHistoryHelperBaseUrl: 'http://127.0.0.1:17373' }), true);
-  assert.equal(helpers.buildAccountRunHistoryRecord({ email: 'a@b.com', password: 'x' }, 'stopped', 'stop'), null);
+  const stoppedRecord = helpers.buildAccountRunHistoryRecord({ email: 'a@b.com', password: 'x' }, 'stopped', 'stop');
+  assert.equal(stoppedRecord.recordId, 'a@b.com');
+  assert.equal(stoppedRecord.email, 'a@b.com');
+  assert.equal(stoppedRecord.password, 'x');
+  assert.equal(stoppedRecord.finalStatus, 'stopped');
+  assert.equal(stoppedRecord.retryCount, 0);
+  assert.equal(stoppedRecord.failureLabel, '流程已停止');
+  assert.equal(stoppedRecord.failureDetail, 'stop');
+  assert.equal(stoppedRecord.failedStep, null);
+  assert.equal(stoppedRecord.source, 'manual');
+  assert.equal(stoppedRecord.autoRunContext, null);
+  assert.ok(stoppedRecord.finishedAt);
 });
 
 test('account run history helper clears persisted records and syncs full snapshot payload to local helper', async () => {
@@ -170,6 +181,7 @@ test('account run history helper clears persisted records and syncs full snapsho
     total: 1,
     success: 0,
     failed: 1,
+    stopped: 0,
     retryTotal: 1,
   });
 
@@ -184,6 +196,7 @@ test('account run history helper clears persisted records and syncs full snapsho
       total: 0,
       success: 0,
       failed: 0,
+      stopped: 0,
       retryTotal: 0,
     },
     records: [],

+ 7 - 6
项目完整链路说明.md

@@ -37,7 +37,7 @@
 - 向后台发送命令
 - 接收后台广播并更新 UI
 - 动态渲染步骤列表
-- 在日志区通过“记录”按钮打开独立的邮箱记录覆盖层,并展示成功/失败/重试统计与分页列表
+- 在日志区通过“记录”按钮打开独立的邮箱记录覆盖层,并展示成功/失败/停止/重试统计与分页列表
 
 ### 2.2 Background Service Worker
 
@@ -136,7 +136,7 @@
 - iCloud 相关偏好
 - LuckMail API 配置
 - 自动运行默认配置
-- 账号运行历史 `accountRunHistory`
+- 账号运行历史 `accountRunHistory`(以邮箱为主键,保存该邮箱最近一次状态:成功/失败/停止)
 - 账号运行历史本地同步开关与 helper 地址
 
 当启用了独立的账号运行历史本地同步配置时,账号运行历史会通过 [scripts/hotmail_helper.py](c:/Users/projectf/Downloads/codex注册扩展/scripts/hotmail_helper.py) 整体同步写入 `data/account-run-history.json` 快照文件,便于开发者直接查看完整记录。
@@ -210,9 +210,10 @@
 1. 解析本轮应使用的邮箱
 2. 打开或复用注册页
 3. 点击注册入口并提交邮箱
-4. 等待邮箱提交后的真实落地页
-5. 如果进入密码页,则继续执行 Step 3
-6. 如果直接进入邮箱验证码页,则自动跳过 Step 3 并进入 Step 4
+4. 以当前邮箱先写入一条“停止(流程尚未完成)”的记录占位
+5. 等待邮箱提交后的真实落地页
+6. 如果进入密码页,则继续执行 Step 3
+7. 如果直接进入邮箱验证码页,则自动跳过 Step 3 并进入 Step 4
 
 ### Step 3
 
@@ -449,7 +450,7 @@
    - 当前轮重试
    - 下一轮继续
 6. 当前轮最终失败时,写入邮箱记录,并在自动重试链路中累计重试次数
-   - 手动停止与自动停止不再进入新邮箱记录体系
+   - 手动停止与自动停止会写入“停止”状态(若后续同邮箱成功/失败,会被覆盖为最新状态)
 7. 如果配置了线程间隔,则挂计时计划
 8. 所有轮次结束后输出汇总
 

+ 3 - 3
项目文件结构说明.md

@@ -40,7 +40,7 @@
 
 ## `background/`
 
-- `background/account-run-history.js`:邮箱记录模块,负责把旧的 append-only 结果流水归一化为成功/失败摘要记录,落地到 `chrome.storage.local`,支持清理记录,并在启用独立本地同步配置后把完整快照同步到本地 helper。
+- `background/account-run-history.js`:邮箱记录模块,负责以邮箱为主键维护最新记录(同邮箱后续状态覆盖),在步骤 2 设定邮箱后支持先写入“停止/未完成”占位状态,统一归一化成功/失败/停止三态并落地到 `chrome.storage.local`,支持清理记录,并在启用独立本地同步配置后把完整快照同步到本地 helper。
 - `background/auto-run-controller.js`:自动运行主控制器,封装多轮执行、重试、轮次摘要、线程间隔与倒计时恢复逻辑;fresh-attempt reset 时会额外保留 `gmailBaseEmail` 与 `mail2925BaseEmail`,避免自动流程重置后丢失别名基邮箱配置。
 - `background/generated-email-helpers.js`:生成邮箱辅助层,除了 Duck / Cloudflare / iCloud / Cloudflare Temp Email,也统一承接 Gmail / 2925 的别名邮箱生成入口。
 - `background/logging-status.js`:后台日志、步骤状态、错误信息和若干状态判断的公共工具层。
@@ -112,7 +112,7 @@
 - `sidepanel/hotmail-manager.js`:侧边栏 Hotmail 账号池管理器,负责列表、导入、验证、测试收信和批量操作。
 - `sidepanel/icloud-manager.js`:侧边栏 iCloud 隐私邮箱管理器,负责列表、筛选、保留、删除和批量操作。
 - `sidepanel/luckmail-manager.js`:侧边栏 LuckMail 管理器,负责邮箱列表、筛选、启停、保留与批量操作。
-- `sidepanel/account-records-manager.js`:侧边栏邮箱记录面板管理器,负责“记录”按钮、覆盖层开关、分页列表、统计摘要和清理确认。
+- `sidepanel/account-records-manager.js`:侧边栏邮箱记录面板管理器,负责“记录”按钮、覆盖层开关、分页列表、成功/失败/停止统计摘要和清理确认。
 - `sidepanel/sidepanel.css`:侧边栏样式文件。
 - `sidepanel/sidepanel.html`:侧边栏页面结构;当前步骤列表已改为动态容器,日志区提供“记录”按钮并挂接邮箱记录覆盖层,同时新增共享“验证码重发”次数输入,并加载 `managed-alias-utils.js`,把旧的“邮箱前缀”字段语义改为“别名基邮箱”。
 - `sidepanel/sidepanel.js`:侧边栏主入口脚本,负责 UI 状态同步、动态步骤渲染、按钮交互、独立本地同步配置、共享验证码自动重发次数配置与广播接收,并装配 Hotmail / iCloud / LuckMail / 邮箱记录面板 manager;同时把 Gmail / 2925 的基邮箱输入、完整注册邮箱输入、自动生成按钮与兼容性校验统一接到共享别名逻辑上。
@@ -126,7 +126,7 @@
 - `tests/auto-run-step6-restart.test.js`:测试自动运行在后半段授权链路遇错时会回到步骤 7 重开,并在命中 add-phone 时停止重开。
 - `tests/auto-step-random-delay.test.js`:测试自动运行步间延迟与旧配置键兼容解析。
 - `tests/background-auto-run-module.test.js`:测试自动运行控制器模块已接入且导出工厂。
-- `tests/background-account-run-history-module.test.js`:测试邮箱记录模块已接入、导出工厂,能够过滤停止记录、归一化失败标签、计算自动重试次数,并支持清理后同步完整快照。
+- `tests/background-account-run-history-module.test.js`:测试邮箱记录模块已接入、导出工厂,能够保留并归一化停止记录、归一化失败标签、计算自动重试次数,并支持清理后同步完整快照。
 - `tests/background-account-history-settings.test.js`:测试账号运行历史的独立配置项归一化,不再复用 Hotmail 模式作为启停条件。
 - `tests/background-generated-email-module.test.js`:测试生成邮箱辅助模块已接入且导出工厂。
 - `tests/background-icloud.test.js`:测试 iCloud 相关后台纯函数与别名收尾逻辑。