73 lines
5.5 KiB
JavaScript
73 lines
5.5 KiB
JavaScript
/* Presentation only: original scores and recommendation rules remain in SkinScore. */
|
||
(function(root, factory) {
|
||
if (typeof module === 'object' && module.exports) module.exports = factory(require('./report-copy.js'));
|
||
else root.ReportUI = factory(root.ReportCopy);
|
||
})(typeof window !== 'undefined' ? window : this, function(Copy) {
|
||
'use strict';
|
||
var defs = [
|
||
['contour', '轮廓', 'firm', 'contour'], ['wrinkles', '皱纹', 'firm', 'wrinkles'],
|
||
['color', '肤色', 'vita', 'tone'], ['smooth', '平滑度', 'vita', 'smooth'], ['water', '水分', 'vita', 'tone'],
|
||
['sens', '泛红', 'stab', 'sens'], ['acne', '痘痘', 'stab', 'acne']
|
||
];
|
||
var products = [
|
||
{ tier: 1, match: '25+束紧精华', title: "1'me 主场精华 I", name: '以我本然有光蓄活', image: 'assets/img/ui-20261009/product-25.png' },
|
||
{ tier: 2, match: '35+支撑精华', title: "1'me 主场精华 II", name: '以我自在有势挺括', image: 'assets/img/ui-20261009/product-35.png' },
|
||
{ tier: 3, match: '50+重塑精华', title: "1'me 主场精华 III", name: '以我从容有态构塑', image: 'assets/img/ui-20261009/product-50.png' }
|
||
];
|
||
var levelMap = { '预警': '改善', '改善': '良好', '良好': '优秀' };
|
||
function numeric(value) { return typeof value === 'number' && isFinite(value); }
|
||
function fill(template, vars) {
|
||
return template.replace(/\{([a-z_]+)\}/g, function(_, key) {
|
||
var v = vars[key];
|
||
return v == null ? '未获取' : numeric(v) ? String(Math.round(v * 100) / 100) : String(v);
|
||
}).replace(/\s+/g, ' ').trim();
|
||
}
|
||
function count(result, key) { var v = result[key]; return v && numeric(v.count) ? v.count : null; }
|
||
function build(vm, result) {
|
||
result = result || {};
|
||
var views = defs.map(function(d) {
|
||
var cat = vm.cats[d[3]], vars = Object.assign({}, cat.vars || {});
|
||
var level = levelMap[cat.level], valid = cat.P != null;
|
||
if (d[0] === 'color' && vars.melanin == null) valid = false;
|
||
if (d[0] === 'water' && vars.water_score == null) valid = false;
|
||
var template = valid && level ? Copy.conclusion[d[0]][level] : '';
|
||
if (d[0] === 'contour') {
|
||
var severity = vars.dark_circle_sev;
|
||
var description = numeric(severity) ? ['无明显黑眼圈', '黑眼圈轻度', '黑眼圈中度', '黑眼圈重度'][severity] : null;
|
||
template = template.replace(/黑眼圈轻\/中\/重度(根据分数给出判断)/g, description || '黑眼圈数据未获取');
|
||
if (vars.la == null || vars.ra == null) template = template.replace(/左右下颌线角度(?:分别为左|左) \{la\}°\/ 右 \{ra\}°[;;]/g, '侧脸角度数据未完整获取;');
|
||
}
|
||
if (d[0] === 'acne') {
|
||
var pustules = count(result, 'acne_pustule'), nodules = count(result, 'acne_nodule');
|
||
var heavy = [pustules > 0 ? '脓包' : '', nodules > 0 ? '结节' : ''].filter(Boolean);
|
||
vars.heavy_note = heavy.length ? ',含' + heavy.join('、') + '等中重度皮损,炎症反应明显' : '';
|
||
if (heavy.length) { level = '改善'; template = Copy.conclusion.acne[level]; }
|
||
else if (vars.acne_cnt > 0 && level === '优秀') { level = '良好'; template = Copy.conclusion.acne[level]; }
|
||
if (vars.acne_cnt == null) template = '本次未获取完整皮损计数,请结合检测图片查看。';
|
||
else if (vars.acne_cnt === 0) template = '本次未检出明显皮损,请结合检测图片查看。';
|
||
}
|
||
// Missing counts are unknown, not zero: remove only the unavailable metric.
|
||
if (vars.fl_cnt == null) template = template.replace(/、细纹 \{fl_cnt\} 条/g, '(细纹计数未获取)');
|
||
if (vars.wr_cnt == null) template = template.replace(/皱纹 \{wr_cnt\} 条/g, '皱纹计数未获取');
|
||
if (vars.water_area == null) template = template.replace(/缺水面积 \{water_area\}%[、,]/g, '缺水面积未获取;');
|
||
if (vars.water_sev == null) template = template.replace(/肌肤缺水比较严重 \{water_sev\},/g, '');
|
||
if (vars.sens_area == null) template = template.replace(/泛红面积(?:达 | )\{sens_area\}%[,;]/g, '泛红面积未获取;');
|
||
if (vars.pore_cnt == null) template = template.replace(/粗大毛孔 \{pore_cnt\} 颗/g, '毛孔计数未获取');
|
||
if (vars.blackhead_cnt == null) template = template.replace(/黑头 \{blackhead_cnt\} 颗/g, '黑头计数未获取');
|
||
var advice = level ? Copy.care[d[0]][level] : null;
|
||
return { key: d[0], name: d[1], dim: d[2], source: d[3], P: cat.P, level: level || null,
|
||
text: valid ? fill(template, vars) : '本次未检出有效数据,请重新拍摄后查看。',
|
||
valid: valid, advice: valid ? advice : null };
|
||
});
|
||
// Preserve selection of the two weakest original categories. Tone expands into
|
||
// color+water advice, with thresholds inherited from the same original category.
|
||
var ranked = Object.keys(vm.cats).filter(function(k) { return vm.cats[k].P != null; })
|
||
.sort(function(a,b) { return vm.cats[a].P - vm.cats[b].P; }).slice(0,2);
|
||
var chosen = views.filter(function(v) { return ranked.indexOf(v.source) >= 0 && v.advice; });
|
||
var care = chosen.map(function(v) { return { name: v.name, text: v.advice.care + v.advice.lifestyle }; });
|
||
var product = products.filter(function(p) { return p.match === vm.essence.name; })[0] || null;
|
||
return { version: Copy.version, dims: { firm: '紧塑力', vita: '透亮感', stab: '稳韧力' }, views: views, care: care, product: product };
|
||
}
|
||
return { build: build, products: products, levelMap: levelMap };
|
||
});
|