diff --git a/apps/backend/src/services/session/session-proof-beijing-time.js b/apps/backend/src/services/session/session-proof-beijing-time.js deleted file mode 100644 index 31213cfc..00000000 --- a/apps/backend/src/services/session/session-proof-beijing-time.js +++ /dev/null @@ -1,31 +0,0 @@ -// @ts-nocheck - -import { - BAIDU_BEIJING_TIME_URL, - BEIJING_TIME_PROOF_CLIP, - BEIJING_TIME_PROOF_VIEWPORT, -} from './session-proof-constants.js' - -export async function captureBeijingTimeProof(browserContext, { screenshotPath }) { - const proofPage = await browserContext.newPage() - - try { - await proofPage.setViewportSize(BEIJING_TIME_PROOF_VIEWPORT) - await proofPage.goto(BAIDU_BEIJING_TIME_URL, { waitUntil: 'domcontentloaded' }) - await proofPage.waitForTimeout(3_000) - await proofPage.evaluate(() => { - window.scrollTo(0, 0) - }) - await proofPage.screenshot({ - path: screenshotPath, - clip: BEIJING_TIME_PROOF_CLIP, - }) - - return { - screenshotPath, - pageUrl: BAIDU_BEIJING_TIME_URL, - } - } finally { - await proofPage.close().catch(() => null) - } -} diff --git a/apps/backend/src/services/session/session-proof-beijing-time.ts b/apps/backend/src/services/session/session-proof-beijing-time.ts new file mode 100644 index 00000000..4805a51b --- /dev/null +++ b/apps/backend/src/services/session/session-proof-beijing-time.ts @@ -0,0 +1,55 @@ +/// + +import { + BAIDU_BEIJING_TIME_URL, + BEIJING_TIME_PROOF_CLIP, + BEIJING_TIME_PROOF_VIEWPORT, +} from './session-proof-constants.js' + +type BrowserPageLike = { + setViewportSize: (viewport: { width: number; height: number }) => Promise + goto: (url: string, options?: { waitUntil?: string }) => Promise + waitForTimeout: (milliseconds: number) => Promise + evaluate: (callback: () => unknown) => Promise + screenshot: (options: { + path: string + clip: { x: number; y: number; width: number; height: number } + }) => Promise + close: () => Promise +} + +type BrowserContextLike = { + newPage: () => Promise +} + +export type BeijingTimeProof = { + screenshotPath: string + pageUrl: string +} + +export async function captureBeijingTimeProof( + browserContext: BrowserContextLike, + { screenshotPath }: { screenshotPath: string }, +): Promise { + const proofPage = await browserContext.newPage() + + try { + await proofPage.setViewportSize(BEIJING_TIME_PROOF_VIEWPORT) + await proofPage.goto(BAIDU_BEIJING_TIME_URL, { waitUntil: 'domcontentloaded' }) + await proofPage.waitForTimeout(3_000) + await proofPage.evaluate(() => { + window.scrollTo(0, 0) + }) + await proofPage.screenshot({ + path: screenshotPath, + clip: BEIJING_TIME_PROOF_CLIP, + }) + + return { + screenshotPath, + pageUrl: BAIDU_BEIJING_TIME_URL, + } + } finally { + await proofPage.close().catch(() => null) + } +} diff --git a/apps/backend/src/services/session/session-proof-constants.js b/apps/backend/src/services/session/session-proof-constants.ts similarity index 82% rename from apps/backend/src/services/session/session-proof-constants.js rename to apps/backend/src/services/session/session-proof-constants.ts index ea2e2785..0b80f9f0 100644 --- a/apps/backend/src/services/session/session-proof-constants.js +++ b/apps/backend/src/services/session/session-proof-constants.ts @@ -1,4 +1,6 @@ export const BAIDU_BEIJING_TIME_URL = 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%8C%97%E4%BA%AC%E6%97%B6%E9%97%B4&fenlei=256&rsv_pq=0xa7d529b30000a6eb&rsv_t=2d404COdLspTa8jnKQl%2FyCU%2BSCmRyb%2BvSqxxjk%2B7E1scokLYTuDbehaQ0Dvq&rqlang=en&rsv_enter=1&rsv_dl=ih_0&rsv_sug3=1&rsv_sug1=1&rsv_sug7=001&rsv_sug2=1&rsv_btype=i&rsp=0&rsv_sug9=es_2_1&rsv_sug=1' +export type RedeemProofMode = 'full' | 'basic' | 'off' + export const BEIJING_TIME_PROOF_VIEWPORT = { width: 1440, height: 860 } export const BEIJING_TIME_PROOF_CLIP = { x: 0, @@ -6,4 +8,4 @@ export const BEIJING_TIME_PROOF_CLIP = { width: BEIJING_TIME_PROOF_VIEWPORT.width, height: 620, } -export const DEFAULT_REDEEM_PROOF_MODE = 'full' +export const DEFAULT_REDEEM_PROOF_MODE: RedeemProofMode = 'full' diff --git a/apps/backend/src/services/session/session-proof-mode.js b/apps/backend/src/services/session/session-proof-mode.ts similarity index 53% rename from apps/backend/src/services/session/session-proof-mode.js rename to apps/backend/src/services/session/session-proof-mode.ts index ffc12500..790ef3a6 100644 --- a/apps/backend/src/services/session/session-proof-mode.js +++ b/apps/backend/src/services/session/session-proof-mode.ts @@ -1,10 +1,18 @@ -// @ts-nocheck - import { runtimeConfig } from '../../config/runtime.js' -import { DEFAULT_REDEEM_PROOF_MODE } from './session-proof-constants.js' +import { DEFAULT_REDEEM_PROOF_MODE, type RedeemProofMode } from './session-proof-constants.js' -export function resolveRedeemProofMode(rawMode = runtimeConfig.redeem.proofMode) { +type RedeemResultForProof = { + classification?: { + success?: boolean + } + redeem?: { + iRet?: number | string + ret?: number | string + } +} | null | undefined + +export function resolveRedeemProofMode(rawMode: unknown = runtimeConfig.redeem.proofMode): RedeemProofMode { const normalized = String(rawMode || '') .trim() .toLowerCase() @@ -16,7 +24,7 @@ export function resolveRedeemProofMode(rawMode = runtimeConfig.redeem.proofMode) return DEFAULT_REDEEM_PROOF_MODE } -export function shouldCaptureBeijingTimeProof(finalResult) { +export function shouldCaptureBeijingTimeProof(finalResult: RedeemResultForProof): boolean { if (finalResult?.classification?.success === true) { return true } diff --git a/apps/backend/src/services/session/session-proof-paths.js b/apps/backend/src/services/session/session-proof-paths.ts similarity index 58% rename from apps/backend/src/services/session/session-proof-paths.js rename to apps/backend/src/services/session/session-proof-paths.ts index 83876666..e8202379 100644 --- a/apps/backend/src/services/session/session-proof-paths.js +++ b/apps/backend/src/services/session/session-proof-paths.ts @@ -1,6 +1,14 @@ import path from 'node:path' -export function buildArtifactPaths(outputDir) { +export type RedeemArtifactPaths = { + redeemPageScreenshotPath: string + beijingTimeScreenshotPath: string + screenshotPath: string + htmlPath: string + resultPath: string +} + +export function buildArtifactPaths(outputDir: string): RedeemArtifactPaths { return { redeemPageScreenshotPath: path.join(outputDir, 'redeem-page.png'), beijingTimeScreenshotPath: path.join(outputDir, 'beijing-time.png'), diff --git a/docs/backend-typescript-migration-plan.md b/docs/backend-typescript-migration-plan.md index 88d109b2..af2a2f05 100644 --- a/docs/backend-typescript-migration-plan.md +++ b/docs/backend-typescript-migration-plan.md @@ -397,6 +397,17 @@ - `npm run typecheck` - `npm run build` - `npm test` 共 139 个用例通过 +74. 腾讯浏览器会话 proof 基础模块迁移到 `.ts`: + - `src/services/session/session-proof-constants.ts` + - `src/services/session/session-proof-paths.ts` + - `src/services/session/session-proof-mode.ts` + - `src/services/session/session-proof-beijing-time.ts` +75. 兑换凭证模式、artifact 路径、北京时间截图浏览器上下文与截图返回值已显式类型化 +76. Docker 内验证通过: + - `src/services/session/session-proof.test.js` 共 4 个用例通过 + - `npm run typecheck` + - `npm run build` + - `npm test` 共 139 个用例通过 ## 下一步建议