(plan)
| 394 | } |
| 395 | |
| 396 | function normalizeAutoRunTimerPlan(plan) { |
| 397 | if (!plan || typeof plan !== 'object' || Array.isArray(plan)) { |
| 398 | return null; |
| 399 | } |
| 400 | |
| 401 | const kind = normalizeAutoRunTimerKind(plan.kind); |
| 402 | if (!kind) { |
| 403 | return null; |
| 404 | } |
| 405 | |
| 406 | const fireAt = Number(plan.fireAt); |
| 407 | if (!Number.isFinite(fireAt)) { |
| 408 | return null; |
| 409 | } |
| 410 | |
| 411 | const totalRuns = normalizeRunCount(plan.totalRuns); |
| 412 | const autoRunSkipFailures = Boolean(plan.autoRunSkipFailures); |
| 413 | const mode = plan.mode === 'continue' ? 'continue' : 'restart'; |
| 414 | const currentRun = Math.max(0, Math.min(totalRuns, Math.floor(Number(plan.currentRun) || 0))); |
| 415 | const attemptRun = Math.max( |
| 416 | 0, |
| 417 | Math.min(AUTO_RUN_MAX_RETRIES_PER_ROUND + 1, Math.floor(Number(plan.attemptRun) || 0)) |
| 418 | ); |
| 419 | const roundSummaries = serializeAutoRunRoundSummaries(totalRuns, plan.roundSummaries); |
| 420 | const countdownTitle = String(plan.countdownTitle || '').trim(); |
| 421 | const countdownNote = String(plan.countdownNote || '').trim(); |
| 422 | |
| 423 | if (kind === AUTO_RUN_TIMER_KIND_SCHEDULED_START) { |
| 424 | return { |
| 425 | kind, |
| 426 | fireAt, |
| 427 | totalRuns, |
| 428 | autoRunSkipFailures, |
| 429 | mode, |
| 430 | currentRun: 0, |
| 431 | attemptRun: 0, |
| 432 | roundSummaries: [], |
| 433 | countdownTitle: countdownTitle || '已计划自动运行', |
| 434 | countdownNote: countdownNote || `计划于 ${formatAutoRunScheduleTime(fireAt)} 开始`, |
| 435 | }; |
| 436 | } |
| 437 | |
| 438 | if (kind === AUTO_RUN_TIMER_KIND_BETWEEN_ROUNDS) { |
| 439 | const normalizedCurrentRun = Math.max(1, Math.min(totalRuns, currentRun)); |
| 440 | const normalizedAttemptRun = Math.max(1, attemptRun); |
| 441 | return { |
| 442 | kind, |
| 443 | fireAt, |
| 444 | totalRuns, |
| 445 | autoRunSkipFailures, |
| 446 | mode: 'restart', |
| 447 | currentRun: normalizedCurrentRun, |
| 448 | attemptRun: normalizedAttemptRun, |
| 449 | roundSummaries, |
| 450 | countdownTitle: countdownTitle || '线程间隔中', |
| 451 | countdownNote: countdownNote || `第 ${Math.min(normalizedCurrentRun + 1, totalRuns)}/${totalRuns} 轮即将开始`, |
| 452 | }; |
| 453 | } |
no test coverage detected