Files
juzi/taobao/scripts/dev-backend.cjs
T
xsl 774376fa16 feat: 完善淘宝小程序拍照、报告与登录流程
接入本地实时识别和自动三连拍,调整报告裁切、商品跳转、分享标题及居中页眉;完善游客会话、后台渠道隔离、部署脚本与回归测试。
2026-11-04 15:07:51 +08:00

50 lines
2.9 KiB
JavaScript

'use strict';
// Local-only fixture backend and gateway simulator. Never contacts Face++/Taobao.
const http = require('node:http'), fs = require('node:fs'), path = require('node:path'), vm = require('node:vm');
const root = path.resolve(__dirname, '../..');
const dataRoot = path.join(root, 'temp/taobao-local-data');
Object.assign(process.env, { NODE_ENV: 'test', PORT: '18181', HOST: '127.0.0.1', PUBLIC_BASE_URL: '',
JUZI_DATA_ROOT: dataRoot, WECHAT_APP_ID: '', WECHAT_APP_SECRET: '',
SKIN_API_KEY: 'local-fixture', SKIN_API_SECRET: 'local-fixture',
TAOBAO_APP_KEY: 'local-fixture', TAOBAO_APP_SECRET: 'local-fixture-not-a-production-secret' });
const context = { window: {} };
vm.runInNewContext(fs.readFileSync(path.join(root, 'h5/assets/mock/report-fixture.js'), 'utf8'), context);
const fixture = JSON.parse(JSON.stringify(context.window.MOCK_FIXTURE));
global.fetch = async () => ({ ok: true, status: 200, json: async () => ({ request_id: 'local-fixture',
result: structuredClone(fixture.result), face_rectangle: fixture.face_rectangle,
left_side_result: fixture.side.left, right_side_result: fixture.side.right }) });
require(path.join(root, 'h5/server'));
const auth = require(path.join(root, 'h5/lib/taobao-auth'));
http.createServer(async (req, res) => {
const url = new URL(req.url, 'http://localhost');
if (url.pathname === '/dev/health') {
res.setHeader('Content-Type', 'application/json');
return res.end(JSON.stringify({ ok: true, fixture: true, data_root: dataRoot }));
}
const chunks = []; let length = 0;
for await (const chunk of req) {
length += chunk.length;
if (length > 128 * 1024) { res.writeHead(413); return res.end(); }
chunks.push(chunk);
}
const raw = Buffer.concat(chunks).toString('utf8');
if (['/api/taobao/session', '/api/taobao/guest-session', '/api/taobao/me'].includes(url.pathname)) {
const query = { app_key: process.env.TAOBAO_APP_KEY, sign_method: 'md5' };
if (url.pathname !== '/api/taobao/guest-session') query.open_id = 'local-development-user';
url.search = new URLSearchParams(query).toString();
const params = Object.fromEntries(url.searchParams);
url.searchParams.set('sign', auth.signature(params, raw, process.env.TAOBAO_APP_SECRET));
}
const headers = { ...req.headers, host: '127.0.0.1:18181', 'content-length': Buffer.byteLength(raw) };
delete headers.origin;
const upstream = http.request({ hostname: '127.0.0.1', port: 18181, path: url.pathname + url.search,
method: req.method, headers }, upstreamRes => {
res.writeHead(upstreamRes.statusCode, upstreamRes.headers); upstreamRes.pipe(res);
});
upstream.on('error', () => { if (!res.headersSent) res.writeHead(502); res.end(); });
upstream.end(raw);
}).listen(18180, '127.0.0.1', () => {
console.log('[local] Gateway simulator + H5: http://127.0.0.1:18180');
console.log('[local] Fixture data only; account/report files: ' + dataRoot);
});