feat: 更新账户运行记录逻辑,支持流程停止状态,优化样式以反映新状态

This commit is contained in:
祁连海
2026-04-17 22:34:30 +08:00
parent f5b622d272
commit 00b66d2157
5 changed files with 30 additions and 11 deletions
+1
View File
@@ -6,3 +6,4 @@
/data/account-run-history.txt /data/account-run-history.txt
/data/account-run-history.json /data/account-run-history.json
.npm-test.log
+1 -4
View File
@@ -1066,6 +1066,7 @@ async function setEmailStateSilently(email) {
async function setEmailState(email) { async function setEmailState(email) {
await setEmailStateSilently(email); await setEmailStateSilently(email);
if (email) { if (email) {
await appendManualAccountRunRecordIfNeeded('step2_stopped', null, '步骤 2 已使用邮箱,流程尚未完成。');
await resumeAutoRunIfWaitingForEmail(); await resumeAutoRunIfWaitingForEmail();
} }
} }
@@ -4696,10 +4697,6 @@ async function appendManualAccountRunRecordIfNeeded(status, stateOverride = null
} }
const state = stateOverride || await getState(); const state = stateOverride || await getState();
if (isAutoRunLockedState(state)) {
return null;
}
return appendAndBroadcastAccountRunRecord(status, state, reason); return appendAndBroadcastAccountRunRecord(status, state, reason);
} }
+12 -6
View File
@@ -72,8 +72,11 @@
if (finalStatus === 'success') { if (finalStatus === 'success') {
return '流程完成'; return '流程完成';
} }
if (finalStatus === 'stopped') {
return '流程已停止';
}
if (finalStatus !== 'failed') { if (finalStatus !== 'failed') {
return ''; return '';
} }
if (isPhoneVerificationFailure(failureDetail)) { if (isPhoneVerificationFailure(failureDetail)) {
return '出现手机号验证'; return '出现手机号验证';
@@ -138,12 +141,12 @@
const password = String(record.password || '').trim(); const password = String(record.password || '').trim();
const finalStatus = normalizeFinalStatus(record.finalStatus || record.status || ''); const finalStatus = normalizeFinalStatus(record.finalStatus || record.status || '');
if (!email || !password || !finalStatus || finalStatus === 'stopped') { if (!email || !password || !finalStatus) {
return null; return null;
} }
const finishedAt = String(record.finishedAt || record.recordedAt || '').trim(); const finishedAt = String(record.finishedAt || record.recordedAt || '').trim();
const failureDetail = finalStatus === 'failed' const failureDetail = finalStatus === 'failed' || finalStatus === 'stopped'
? String(record.failureDetail || record.reason || '').trim() ? String(record.failureDetail || record.reason || '').trim()
: ''; : '';
const failedStepCandidate = Number(record.failedStep); const failedStepCandidate = Number(record.failedStep);
@@ -204,14 +207,14 @@
function buildAccountRunHistoryRecord(state = {}, status = '', reason = '') { function buildAccountRunHistoryRecord(state = {}, status = '', reason = '') {
const email = String(state.email || '').trim(); const email = String(state.email || '').trim();
const password = String(state.password || state.customPassword || '').trim(); const password = String(state.password || state.customPassword || '').trim() || '无';
const finalStatus = normalizeFinalStatus(status); const finalStatus = normalizeFinalStatus(status);
if (!email || !password || !finalStatus || finalStatus === 'stopped') { if (!email || !finalStatus) {
return null; return null;
} }
const failureDetail = finalStatus === 'failed' ? String(reason || '').trim() : ''; const failureDetail = finalStatus === 'failed' || finalStatus === 'stopped' ? String(reason || '').trim() : '';
const failedStep = finalStatus === 'failed' ? extractFailedStep(status, failureDetail) : null; const failedStep = finalStatus === 'failed' ? extractFailedStep(status, failureDetail) : null;
const source = Boolean(state.autoRunning) ? 'auto' : 'manual'; const source = Boolean(state.autoRunning) ? 'auto' : 'manual';
const autoRunContext = source === 'auto' ? buildAutoRunContextFromState(state) : null; const autoRunContext = source === 'auto' ? buildAutoRunContextFromState(state) : null;
@@ -271,6 +274,8 @@
summary.success += 1; summary.success += 1;
} else if (record.finalStatus === 'failed') { } else if (record.finalStatus === 'failed') {
summary.failed += 1; summary.failed += 1;
} else if (record.finalStatus === 'stopped') {
summary.stopped += 1;
} }
summary.retryTotal += normalizeRetryCount(record.retryCount); summary.retryTotal += normalizeRetryCount(record.retryCount);
return summary; return summary;
@@ -278,6 +283,7 @@
total: 0, total: 0,
success: 0, success: 0,
failed: 0, failed: 0,
stopped: 0,
retryTotal: 0, retryTotal: 0,
}); });
} }
+1 -1
View File
@@ -145,7 +145,7 @@ def normalize_account_run_snapshot_record(record):
email_addr = str(record.get("email") or "").strip() email_addr = str(record.get("email") or "").strip()
password = str(record.get("password") or "").strip() password = str(record.get("password") or "").strip()
final_status = str(record.get("finalStatus") or "").strip().lower() final_status = str(record.get("finalStatus") or "").strip().lower()
if not email_addr or not password or final_status not in {"success", "failed"}: if not email_addr or not password or final_status not in {"success", "failed", "stopped"}:
return None return None
finished_at = str(record.get("finishedAt") or "").strip() or datetime.now(timezone.utc).isoformat().replace("+00:00", "Z") finished_at = str(record.get("finishedAt") or "").strip() or datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+15
View File
@@ -1785,6 +1785,12 @@ header {
border-color: color-mix(in srgb, var(--blue) 16%, var(--border)); border-color: color-mix(in srgb, var(--blue) 16%, var(--border));
} }
.account-records-stat.is-stopped {
color: var(--amber);
background: var(--amber-soft);
border-color: color-mix(in srgb, var(--amber) 16%, var(--border));
}
.account-records-list { .account-records-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1908,6 +1914,15 @@ header {
color: var(--red); color: var(--red);
} }
.account-record-item.is-stopped {
border-color: color-mix(in srgb, var(--amber) 14%, var(--border-subtle));
}
.account-record-item.is-stopped .account-record-item-status {
background: var(--amber-soft);
color: var(--amber);
}
.account-records-pagination { .account-records-pagination {
display: flex; display: flex;
align-items: center; align-items: center;