feat(h5): apply fourth feedback and tighten local capture validation

This commit is contained in:
xsl
2026-10-12 20:16:41 +08:00
parent e53c809522
commit 92a3965b7d
33 changed files with 3758 additions and 1385 deletions
+41 -1
View File
@@ -85,6 +85,12 @@ function ageText(age) { return age == null ? '-' : esc(age) + '岁'; }
function skinAgeHtml(r) {
return '<b>原始 ' + ageText(r.skin_age) + '</b><div class="sub">展示 ' + ageText(r.skin_age_display) + '</div>';
}
function captureQualityHtml(r) {
var q = r.capture_quality;
if (!q) return '';
var label = q.status === 'invalid' ? '侧脸质量异常(未拦截)' : q.status === 'unavailable' ? '侧脸质量未获取' : '侧脸质量有效';
return '<div class="sub">' + esc(label) + '</div>';
}
function productName(name) {
for (var i = 0; i < ReportUI.products.length; i++) {
var p = ReportUI.products[i];
@@ -135,7 +141,7 @@ function loadRecords() {
'<td>' + thumb + '</td>' +
'<td class="mono">' + esc(it.record_id) + (it.retry_of ? '<div class="sub">重试自 ' + esc(it.retry_of) + '</div>' : '') + '</td>' +
'<td>' + profileHtml(it) + '</td>' +
'<td>' + esc(it.shoot_status) + '</td>' +
'<td>' + esc(it.shoot_status) + captureQualityHtml(it) + '</td>' +
'<td>' + esc(it.upload_status) + '</td>' +
'<td><span class="st ' + (ST_CLASS[it.detect_status] || '') + '">' + esc(it.detect_status) + '</span>' +
(it.fail_code ? '<div class="sub">' + esc(it.fail_code) + '</div>' : '') + '</td>' +
@@ -355,6 +361,17 @@ function renderDetail(data) {
'<span>被重试次数 <b>' + (r.retry_count || 0) + '</b></span>' +
'</div>');
/* 档案 */
if (r.capture_quality || r.capture_diagnostics) {
var quality = captureQualityHtml(r);
if (r.capture_quality) ['left', 'right'].forEach(function (key) {
var view = r.capture_quality.views[key];
quality += '<p>' + (key === 'left' ? '左脸' : '右脸') + ':quality=' + esc(view.quality == null ? '未获取' : view.quality) + ',角度=' + esc(view.angle == null ? '未获取' : view.angle) + ',状态=' + esc(view.status) + '</p>';
});
if (r.capture_diagnostics) quality += '<p>前端参数版本:' + esc(r.capture_diagnostics.version) + '(客户端自报,仅作校准参考)</p><pre class="d-copy">' + esc(JSON.stringify(r.capture_diagnostics, null, 2)) + '</pre>';
h += dSec('拍摄质量与前端校准', quality);
}
/* 档案 */
h += dSec('档案信息', '<div class="d-kv">' +
'<span>实际年龄 <b>' + ageText(r.real_age) + '</b></span>' +
@@ -432,6 +449,29 @@ function renderDetail(data) {
if (r.lifestyle) copyHtml += '<div class="d-copy"><b>生活方式:</b>' + esc(r.lifestyle) + '</div>';
if (copyHtml) h += dSec(presentation ? '前端报告结论(保存快照)与计算摘要' : '旧版生成文案(无前端快照)', copyHtml);
// Technical region metrics stay in the protected admin, not customer prose.
var wrinkleView = presentation && presentation.views && presentation.views.filter(function(view) { return view.key === 'wrinkles'; })[0];
var wrinkleRows = wrinkleView && wrinkleView.details;
if (!wrinkleRows && data.raw_json && data.raw_json.result) wrinkleRows = ReportUI.wrinkleDetails(data.raw_json.result);
if (wrinkleRows) {
var metricDefs = [['wrinkle_score', '皱纹分'], ['wrinkle_severity_level', '严重等级'],
['wrinkle_deep_num', '深纹条数'], ['wrinkle_shallow_num', '浅纹条数'],
['wrinkle_norm_length', '标准化长度'], ['wrinkle_norm_depth', '标准化深度'],
['wrinkle_pixel_density', '像素密度'], ['wrinkle_area_ratio', '面积比例'], ['wrinkle_deep_ratio', '深纹比例']];
var wrinkleHead = '<th>分区</th>', wrinkleBody = '';
metricDefs.forEach(function(metric) { wrinkleHead += '<th>' + metric[1] + '</th>'; });
wrinkleRows.forEach(function(row) {
wrinkleBody += '<tr><td>' + esc(row.name) + '</td>';
metricDefs.forEach(function(metric) {
var value = row.metrics[metric[0]];
wrinkleBody += '<td>' + (value == null ? '未获取' : esc(String(value))) + '</td>';
});
wrinkleBody += '</tr>';
});
h += dSec('皱纹分区原始指标(仅后台复核;左右以本人为准)', '<div style="overflow-x:auto"><table class="d-table"><thead><tr>' +
wrinkleHead + '</tr></thead><tbody>' + wrinkleBody + '</tbody></table></div>');
}
var care = presentation ? presentation.care : r.careAdvice;
if (care && care.length) {
var advice = '';