From 60cf55f75549b0f2f48604af9e128039c823d0c6 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 17 Jun 2026 09:50:34 +0800 Subject: [PATCH] feat: add progress display helpers --- src/lib/progress/__tests__/progress.test.ts | 36 ++++++++++++++++++ src/lib/progress/progress.ts | 41 +++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/lib/progress/__tests__/progress.test.ts create mode 100644 src/lib/progress/progress.ts diff --git a/src/lib/progress/__tests__/progress.test.ts b/src/lib/progress/__tests__/progress.test.ts new file mode 100644 index 0000000..65c6207 --- /dev/null +++ b/src/lib/progress/__tests__/progress.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from "vitest"; + +import { + formatElapsedSeconds, + getElapsedNotice, + getProgressStages, +} from "../progress"; + +describe("progress helpers", () => { + it("formats elapsed seconds as short Chinese text", () => { + expect(formatElapsedSeconds(0)).toBe("0 秒"); + expect(formatElapsedSeconds(39)).toBe("39 秒"); + expect(formatElapsedSeconds(65)).toBe("1 分 5 秒"); + }); + + it("uses a neutral 10-40 second expectation without naming a model", () => { + expect(getElapsedNotice(5)).toBe("通常需要 10-40 秒,请保持页面打开。"); + expect(getElapsedNotice(45)).toBe("仍在处理中,请保持页面打开。"); + expect(getElapsedNotice(75)).toBe("耗时较长,仍在等待服务返回。"); + expect(getElapsedNotice(5)).not.toMatch(/DeepSeek|OpenAI|模型|model/i); + }); + + it("returns stage labels for analyze and optimize actions", () => { + expect(getProgressStages("analyze").map((stage) => stage.label)).toEqual([ + "读取文章输入", + "提取事实卡", + "生成待确认信息", + ]); + expect(getProgressStages("optimize").map((stage) => stage.label)).toEqual([ + "生成优化稿", + "质量检查", + "必要时定向修复", + "整理结果", + ]); + }); +}); diff --git a/src/lib/progress/progress.ts b/src/lib/progress/progress.ts new file mode 100644 index 0000000..ac10351 --- /dev/null +++ b/src/lib/progress/progress.ts @@ -0,0 +1,41 @@ +export type ProgressAction = "analyze" | "confirm" | "optimize"; + +export interface ProgressStage { + label: string; +} + +const progressStages: Record = { + analyze: [ + { label: "读取文章输入" }, + { label: "提取事实卡" }, + { label: "生成待确认信息" }, + ], + confirm: [ + { label: "校验事实卡" }, + { label: "保存品牌事实" }, + ], + optimize: [ + { label: "生成优化稿" }, + { label: "质量检查" }, + { label: "必要时定向修复" }, + { label: "整理结果" }, + ], +}; + +export function formatElapsedSeconds(seconds: number) { + const safeSeconds = Math.max(0, Math.floor(seconds)); + if (safeSeconds < 60) return `${safeSeconds} 秒`; + const minutes = Math.floor(safeSeconds / 60); + const remainingSeconds = safeSeconds % 60; + return `${minutes} 分 ${remainingSeconds} 秒`; +} + +export function getElapsedNotice(seconds: number) { + if (seconds >= 60) return "耗时较长,仍在等待服务返回。"; + if (seconds >= 40) return "仍在处理中,请保持页面打开。"; + return "通常需要 10-40 秒,请保持页面打开。"; +} + +export function getProgressStages(action: ProgressAction) { + return progressStages[action]; +}