feat(report): add annotated wrinkle views and restore capture countdown

This commit is contained in:
xsl
2026-10-15 19:45:21 +08:00
parent 2d80f6dfd0
commit 757b96dfad
23 changed files with 396 additions and 75 deletions
+15
View File
@@ -28,6 +28,7 @@ const RECORDS_FILE = path.join(DATA_ROOT, 'records.jsonl'); // 检测记录(一
const ReportUI = require('./js/report-ui.js');
const BeijingTime = require('./js/beijing-time.js');
const CaptureDiagnostics = require('./lib/capture-diagnostics.js');
const WrinkleViews = require('./lib/wrinkle-views.js');
const accounts = require('./lib/accounts.js')(path.join(DATA_ROOT, 'accounts'));
/* 服务端评分引擎:与 C 端同一份公式(禁止复制公式,直接复用) */
@@ -291,6 +292,9 @@ function fillSuccess(rec, fpJson, persist = true) {
rec.wrinkle_score_rule = vm.wrinkleScoreRule;
rec.acne_scoring = vm.cats.acne.vars.acne_scoring;
rec.tone_scoring = vm.cats.tone.vars.tone_scoring;
rec.wrinkle_view_status = fpJson.wrinkle_views ? Object.fromEntries(['left','right'].map(view => [view, {
status:fpJson.wrinkle_views[view]?.status||'unavailable', error_code:fpJson.wrinkle_views[view]?.error_code||null
}])) : null;
rec.jawline_angle_l = jawlineAngle(fpJson.left_side_result, 'left');
rec.jawline_angle_r = jawlineAngle(fpJson.right_side_result, 'right');
rec.cats = {}; rec.copy_6 = {};
@@ -326,6 +330,15 @@ async function runDetect(rec, front, left, right, persist = true) {
rec.updated_at = nowIso();
const t0 = Date.now();
const fpJson = await callFacepp(front, left, right);
if (fpJson.result && !fpJson.error_message) {
fpJson.wrinkle_views = await WrinkleViews.collect(fpJson,{left,right},{
key:CRED.key,secret:CRED.secret,url:FACEPP_URL,
gapMs:process.env.NODE_ENV==='test'?0:4000,
// Keep within the existing 150-second browser timeout, including
// upload/serialization headroom. Missing side maps never fail a report.
deadline:t0+120000
});
}
rec.cost_ms = Date.now() - t0;
if (fpJson.error_message) {
const code = fpJson.error_message.split(':')[0];
@@ -466,6 +479,7 @@ async function handleAnalyze(req, res) {
const nested = fpJson.side_result || {};
const payload = {
result, face_rectangle: fpJson.face_rectangle || null,
wrinkle_views: WrinkleViews.forReport(fpJson.wrinkle_views),
side: { left: fpJson.left_side_result || nested.left_side_result || null,
right: fpJson.right_side_result || nested.right_side_result || null }
};
@@ -485,6 +499,7 @@ async function handleAnalyze(req, res) {
ok: true,
record_id: recordId, report_saved: reportSaved, presentation, vm: snapshotVm,
result,
wrinkle_views: payload.wrinkle_views,
face_rectangle: fpJson.face_rectangle || null,
side: {
left: fpJson.left_side_result || nested.left_side_result || null,