fix(recommendation): use displayed skin age across reports and admin

This commit is contained in:
xsl
2026-10-16 19:03:25 +08:00
parent 571d78a2ed
commit bb6da17f54
12 changed files with 106 additions and 35 deletions
+22 -7
View File
@@ -628,12 +628,12 @@
var firm = isNum(scores.firm) ? scores.firm : null;
var vita = isNum(scores.vita) ? scores.vita : null;
var stab = isNum(scores.stab) ? scores.stab : null;
var rec = { version: '2026-10-12-skin-age-v1', skinAge: skinAge,
var rec = { version: '2026-10-16-display-skin-age-v2', ageBasis: 'display', skinAge: skinAge,
baseTier: null, tier: null, boundary: null, adjustment: 'none',
scores: { firm: firm, vita: vita, stab: stab }, reason: '', triggers: [] };
if (!isNum(skinAge) || skinAge <= 0) {
rec.adjustment = 'unavailable';
rec.reason = '未获取有效原始肌龄,暂不推荐具体产品;不以实际年龄代替。';
rec.reason = '未获取有效展示肌龄,暂不推荐具体产品;不以实际年龄代替。';
return rec;
}
rec.baseTier = skinAge < 35 ? 1 : (skinAge < 50 ? 2 : 3);
@@ -653,11 +653,11 @@
rec.reason = '处于' + rec.boundary + '岁上侧边界,紧塑力≥9且透亮感或稳韧力≥9,降一档。';
rec.triggers.push(rec.boundary + '岁边界高分降档');
} else if (skinAge < 32) {
rec.reason = '原始肌龄小于32岁,固定推荐25+,轮廓或皱纹低分不升档。';
rec.reason = '展示肌龄小于32岁,固定推荐25+,轮廓或皱纹低分不升档。';
} else if (rec.boundary != null) {
rec.reason = '处于' + rec.boundary + '岁边界,未满足升降档条件,保持肤龄基础档。';
} else {
rec.reason = '不在35±3或50±3岁边界内,仅按原始肌龄推荐。';
rec.reason = '不在35±3或50±3岁边界内,仅按展示肌龄推荐。';
}
return rec;
}
@@ -777,7 +777,7 @@
if (!worst || cP < worst.P) worst = { catKey: def.key, name: def.name, P: cP, S: sShow(cP) };
}
var recommendation = recommendProduct(skinAge, {
var recommendation = recommendProduct(skinAgeDisplay, {
firm: dims.firm.P == null ? null : sRaw(dims.firm.P),
vita: dims.vita.P == null ? null : sRaw(dims.vita.P),
stab: dims.stab.P == null ? null : sRaw(dims.stab.P)
@@ -934,7 +934,7 @@
};
// Apply the current display rule to new and historical reports without
// modifying their raw age, stored snapshot, copy or recommendation.
// modifying their raw age or stored snapshot. Recommendation uses this age.
function reportSkinAge(vm, result) {
var raw = vm && Object.prototype.hasOwnProperty.call(vm, 'skinAgeRaw') ? val(vm.skinAgeRaw) : val(result && result.skin_age);
if (!isNum(raw) || raw < 0) return null;
@@ -942,7 +942,22 @@
if (!isNum(actual) || actual < 0) return raw;
return Math.max(actual - 5, Math.min(actual + 5, raw));
}
function withDisplayRecommendation(vm, result) {
if (!vm) return vm;
var age = reportSkinAge(vm, result), scores = {};
['firm','vita','stab'].forEach(function(key) {
var d = vm.dims && vm.dims[key];
var saved = vm.recommendation && vm.recommendation.scores && vm.recommendation.scores[key];
scores[key] = isNum(saved) ? saved : d && isNum(d.P) ? sRaw(d.P) : d && isNum(d.S) ? d.S : null;
});
var recommendation = recommendProduct(age, scores), tier = recommendation.tier;
return Object.assign({}, vm, { skinAgeDisplay: age, recommendation: recommendation,
group: tier == null ? null : ['25+组','35+组','50+组'][tier-1],
essence: { name: tier == null ? '暂无法推荐' : ESSENCE[tier].name,
text: tier == null ? recommendation.reason : ESSENCE[tier].text, tier: tier, triggers: recommendation.triggers } });
}
return {
withDisplayRecommendation: withDisplayRecommendation,
capDimensionScore: capDimensionScore,
weightedTotal: weightedTotal,
reportSkinAge: reportSkinAge,
@@ -1020,7 +1035,7 @@ if (typeof require === 'function' && typeof module !== 'undefined' && require.ma
ok(vm2.dims.firm.P === Math.min(vm2.cats.contour.P, vm2.cats.wrinkles.P)
&& vm2.dims.vita.P === Math.min(vm2.cats.smooth.P, vm2.cats.tone.P)
&& vm2.dims.stab.P === Math.min(vm2.cats.sens.P, vm2.cats.acne.P), '三维度 P = min(旗下两分类)');
ok(vm2.group === '25+组', '实际年龄40不影响推荐,原始肌龄20仍为25+组');
ok(vm2.group === '35+组', '实际年龄40、原始肌龄20、展示肌龄35,按展示肌龄推荐35+组');
console.log('== T3 原始肌龄展示 ==');
var r3 = clone(SS.MOCK_RESULT);