后端迁移会话凭证渲染模块

This commit is contained in:
yml
2026-05-21 15:17:18 +08:00
parent 52c0c101a6
commit ae31fe2797
4 changed files with 77 additions and 14 deletions
@@ -1,4 +1,16 @@
export function buildProofHtml({ redeemImageBase64, timeImageBase64, redeemMessage, timePageUrl }) { export type ProofHtmlInput = {
redeemImageBase64: string
timeImageBase64: string
redeemMessage?: string
timePageUrl: string
}
export function buildProofHtml({
redeemImageBase64,
timeImageBase64,
redeemMessage,
timePageUrl,
}: ProofHtmlInput): string {
const capturedAt = new Date().toLocaleString('zh-CN', { const capturedAt = new Date().toLocaleString('zh-CN', {
hour12: false, hour12: false,
timeZone: 'Asia/Shanghai', timeZone: 'Asia/Shanghai',
@@ -159,7 +171,7 @@ export function buildProofHtml({ redeemImageBase64, timeImageBase64, redeemMessa
</html>` </html>`
} }
export function escapeHtml(value) { export function escapeHtml(value: unknown): string {
return String(value || '') return String(value || '')
.replaceAll('&', '&amp;') .replaceAll('&', '&amp;')
.replaceAll('<', '&lt;') .replaceAll('<', '&lt;')
@@ -1,14 +1,37 @@
// @ts-nocheck /// <reference lib="dom" />
import fs from 'node:fs/promises' import fs from 'node:fs/promises'
import { buildProofHtml } from './session-proof-html.js' import { buildProofHtml } from './session-proof-html.js'
export async function showResultDialog(page, message) { type BrowserPageLike = {
evaluate: <T = unknown>(callback: any, arg?: unknown) => Promise<T>
waitForTimeout: (milliseconds: number) => Promise<void>
setViewportSize: (viewport: { width: number; height: number }) => Promise<void>
setContent: (html: string, options?: { waitUntil?: string }) => Promise<unknown>
screenshot: (options: { path: string; fullPage?: boolean }) => Promise<unknown>
close: () => Promise<void>
}
type BrowserContextLike = {
newPage: () => Promise<BrowserPageLike>
}
type ComposeProofScreenshotOptions = {
outputPath: string
redeemImagePath: string
timeImagePath: string
redeemMessage?: string
timePageUrl: string
}
export async function showResultDialog(page: BrowserPageLike, message: string): Promise<void> {
await page.evaluate((text) => { await page.evaluate((text) => {
document.querySelectorAll('iframe').forEach((element) => element.remove()) document.querySelectorAll('iframe').forEach((element) => element.remove())
document.querySelectorAll('.pop').forEach((element) => { document.querySelectorAll('.pop').forEach((element) => {
element.style.display = 'none' if (element instanceof HTMLElement) {
element.style.display = 'none'
}
}) })
let card = document.getElementById('codex-redeem-result') let card = document.getElementById('codex-redeem-result')
@@ -80,9 +103,9 @@ export async function showResultDialog(page, message) {
} }
export async function composeProofScreenshot( export async function composeProofScreenshot(
browserContext, browserContext: BrowserContextLike,
{ outputPath, redeemImagePath, timeImagePath, redeemMessage, timePageUrl }, { outputPath, redeemImagePath, timeImagePath, redeemMessage, timePageUrl }: ComposeProofScreenshotOptions,
) { ): Promise<void> {
const [redeemImageBase64, timeImageBase64] = await Promise.all([ const [redeemImageBase64, timeImageBase64] = await Promise.all([
fs.readFile(redeemImagePath, 'base64'), fs.readFile(redeemImagePath, 'base64'),
fs.readFile(timeImagePath, 'base64'), fs.readFile(timeImagePath, 'base64'),
@@ -1,11 +1,29 @@
// @ts-nocheck
import fs from 'node:fs/promises' import fs from 'node:fs/promises'
import { BAIDU_BEIJING_TIME_URL } from './session-proof-constants.js' import { BAIDU_BEIJING_TIME_URL, type RedeemProofMode } from './session-proof-constants.js'
type RedeemResultFilePayload = {
proofMode: RedeemProofMode
sessionId?: string
activityUrl: string
code: string
finalResult?: {
role?: {
area?: string
}
[key: string]: unknown
} | null
attempts?: unknown[]
screenshotPath: string
htmlPath?: string
redeemPageScreenshotPath?: string
beijingTimeScreenshotPath?: string
beijingTimePageUrl?: string
beijingTimeError?: string
}
export async function writeRedeemResultFile( export async function writeRedeemResultFile(
resultPath, resultPath: string,
{ {
proofMode, proofMode,
sessionId, sessionId,
@@ -19,8 +37,8 @@ export async function writeRedeemResultFile(
beijingTimeScreenshotPath = '', beijingTimeScreenshotPath = '',
beijingTimePageUrl = BAIDU_BEIJING_TIME_URL, beijingTimePageUrl = BAIDU_BEIJING_TIME_URL,
beijingTimeError = '', beijingTimeError = '',
}, }: RedeemResultFilePayload,
) { ): Promise<void> {
await fs.writeFile( await fs.writeFile(
resultPath, resultPath,
JSON.stringify( JSON.stringify(
+10
View File
@@ -408,6 +408,16 @@
- `npm run typecheck` - `npm run typecheck`
- `npm run build` - `npm run build`
- `npm test` 共 139 个用例通过 - `npm test` 共 139 个用例通过
77. 腾讯浏览器会话 proof 渲染 / 结果写入模块迁移到 `.ts`
- `src/services/session/session-proof-html.ts`
- `src/services/session/session-proof-renderer.ts`
- `src/services/session/session-proof-result-writer.ts`
78. 凭证 HTML 输入、结果 JSON payload、浏览器截图合成上下文、页面弹窗渲染已显式类型化
79. Docker 内验证通过:
- `src/services/session/session-proof.test.js` 共 4 个用例通过
- `npm run typecheck`
- `npm run build`
- `npm test` 共 139 个用例通过
## 下一步建议 ## 下一步建议