数字我 Digital Me:全量入库(大文件走 Git LFS)
nginx serve /uploads direct (audio speed) / patch-nginx (push) Failing after 1m34s

This commit is contained in:
2026-10-10 16:24:43 +08:00
commit 0593ff7e62
1893 changed files with 361723 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
// 用 CDP 给页面注入 dm_token 后截图(验证需登录的后台)。
// 用法:node scripts/cdp-shot.mjs <token> <targetPath> <outPng>
// 前置:chrome 已带 --remote-debugging-port=9222 启动,并已打开 http://localhost:5173/login
import WebSocket from 'ws';
import { writeFileSync } from 'node:fs';
const [, , TOKEN, TARGET, OUT] = process.argv;
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
async function listTargets() {
const res = await fetch('http://localhost:9222/json/list');
return res.json();
}
async function main() {
// 找到 5173 的页面 target。
let ws = '';
for (let i = 0; i < 30; i++) {
const ts = await listTargets();
const t = ts.find((x) => x.type === 'page' && /localhost:5173/.test(x.url));
if (t) { ws = t.webSocketDebuggerUrl; break; }
await wait(300);
}
if (!ws) throw new Error('no 5173 page target');
const sock = new WebSocket(ws, { perMessageDeflate: false, maxPayload: 64 * 1024 * 1024 });
let id = 0;
const pending = new Map();
const send = (method, params = {}) =>
new Promise((resolve) => { const mid = ++id; pending.set(mid, resolve); sock.send(JSON.stringify({ id: mid, method, params })); });
await new Promise((r) => sock.on('open', r));
sock.on('message', (buf) => {
const msg = JSON.parse(buf.toString());
if (msg.id && pending.has(msg.id)) { pending.get(msg.id)(msg.result); pending.delete(msg.id); return; }
if (msg.method === 'Network.responseReceived') {
const u = msg.params?.response?.url || '';
if (/\/api\//.test(u)) console.log(' NET', msg.params.response.status, u.replace('http://localhost:3701', ''));
}
if (msg.method === 'Runtime.exceptionThrown') console.log(' EXC', msg.params?.exceptionDetails?.text, msg.params?.exceptionDetails?.exception?.description?.slice(0, 120));
});
await send('Page.enable');
await send('Runtime.enable');
await send('Network.enable');
// 先到根页把 token 写进 localStorage。
await send('Page.navigate', { url: 'http://localhost:5173/' });
await wait(2500);
const set = await send('Runtime.evaluate', {
expression: `localStorage.setItem('dm_token', ${JSON.stringify(TOKEN)}); localStorage.getItem('dm_token')?.length || 0`,
returnByValue: true,
});
console.log('token len in storage:', set?.result?.value);
// 第一次整页跳(预热会话,冷启动可能被守卫弹走)。
await send('Runtime.evaluate', { expression: `location.href='http://localhost:5173${TARGET}'` });
await wait(5000);
// 第二次跳目标(此时 store 已 authed、user 已拉取 → 稳定停在目标页)。
await send('Page.navigate', { url: `http://localhost:5173${TARGET}` });
await wait(6000);
const diag = await send('Runtime.evaluate', {
expression: `JSON.stringify({path: location.pathname, tok: (localStorage.getItem('dm_token')||'').length, h1: document.querySelector('h1')?.textContent?.slice(0,20), bodyHas: document.body.innerText.includes('大师墙')})`,
returnByValue: true,
});
console.log('after nav:', diag?.result?.value);
const { data } = await send('Page.captureScreenshot', { format: 'png', captureBeyondViewport: true });
writeFileSync(OUT, Buffer.from(data, 'base64'));
console.log('saved', OUT);
sock.close();
process.exit(0);
}
main().catch((e) => { console.error(e); process.exit(1); });