feat(scoring): use independent tone hydration minima and focus-first care
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# 七项护理选三与关注优先
|
||||
|
||||
护理候选项按文档顺序为轮廓、皱纹、肤色、平滑度、水分、泛红、痘痘。使用未四舍五入的百分制分数,缺失/无效项剔除。
|
||||
|
||||
肤色独立采用color_score(扣斑后的色素80%+黑眼圈20%);水分独立采用已有交叉校验后的水分项。其他项使用各自现有P。肤色分析文案和护理分档同步使用独立肤色项,黑眼圈描述仍按真实检测程度;水分独立分档保持。小项P仅用于展示与护理选择,不调整维度或综合分。
|
||||
|
||||
1. 依小项P升序选择全局最低三项;同分时,当前优先关注大维度中的项优先,再按上述文档顺序固定选择。
|
||||
2. 只在入选三项中,将属于优先关注大维度的项整体前置;组内P仍低分优先。不额外插入高分的关注项。
|
||||
3. 各项按自己的分档取护理和生活方式全文拼接。低于80改善、80至低于90良好、90以上优秀;保留痘痘脓包/结节改善档、有皮损不优秀等现有文案约束。
|
||||
4. 不足三项按有效数量展示,全部缺失显示原有无建议提示。
|
||||
|
||||
用户提供的本轮护理全文同步到reference和report-copy。原文比对发现皱纹改善档生活方式需删除旧版开头“保证睡眠,”,本次已修正,其余沿用用户提供文本。
|
||||
|
||||
新presentation新增careRule=seven-lowest-three-focus-first-v1;care条目保留key、name、dim、P、level、priority供核查,页面仅展示原有编号和正文。产品三选一、原始评分、历史快照和历史推荐不变;历史保存的护理文案不批量重生成。
|
||||
|
||||
## 真实案例回放
|
||||
|
||||
R20261015-111214-JKNS:关注紧塑力。肤色58.8、皱纹73、平滑度88.9为全局最低三项,最终皱纹→肤色→平滑度;水分97不入选,总分94不变。
|
||||
|
||||
R20261014-171215-CYLF:关注紧塑力。皱纹65、平滑度87.6、肤色88.8入选,最终顺序不变;水分93不入选,总分94不变。
|
||||
|
||||
## 验证
|
||||
|
||||
care-selection.js覆盖关注项两项/一项/零项、全部关注项、同分选取与固定顺序、原始小数、不足三项/全缺失、肤色水分独立档位、痘痘约束、全文一致与输入不变。同步复测肤色、水分、账号、持久化、历史快照、推荐、报告底部长文案布局和旧评分回归。
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
ui-20261015/product-25.png 对应1:69(481×511),product-35.png 对应1:75(481×511),product-50.png 对应1:87(481×511),product-badge.png 对应1:71(101×77)。全部为设计工具导出原始PNG,保留透明边角和原始裁切,无运行时临时素材URL;网页每次只加载选中的产品图。
|
||||
|
||||
产品卡按945×511比例,右侧图按481×511比例,徽标按101×77比例。布局以1080px设计稿折算375px基准并随屏幕缩放,320px屏幕略缩产品文字避免遮挡。
|
||||
产品卡按945×511比例,右侧图按481×511比例,徽标按101×77比例。布局以1080px设计稿折算375px基准并随屏幕缩放。用户最新确认产品标题恢复原来14.467593px,灰色副标题按同一比例(约1.041667)放大到12.013166px,行距同比放大;320px屏幕也保持同一字号,已核对三款文字均不遮挡图片。
|
||||
|
||||
## 验证
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# 水分文案独立分档
|
||||
|
||||
问题案例 R20261015-111214-JKNS:接口水分97、缺水严重度3、缺水面积3%,色素66、黑眼圈30,合成肤色水润77.9。旧版水分文案跟随合成分档,错误套用改善档的含水量偏低、缺水比较严重。
|
||||
|
||||
## 本次修正
|
||||
|
||||
- 水分展示文案及其护理/生活方式建议独立使用水分项:低于80改善,80至低于90良好,90及以上优秀。
|
||||
- 沿用原有交叉校验:水分分≥80且缺水严重度≥60时,按100−严重度评估,并明确提示分数与缺水指标不一致,不默默套用缺水文案。
|
||||
- 改善档不再固定描述严重缺水。严重度为有效0~100时,≥60描述缺水程度较高,其他值仅报告严重度;缺失省略。缺水面积缺失也不当成0。
|
||||
- 缺失或无效水分分不产生水分档位及水分护理建议。
|
||||
- 三维度、综合得分、产品推荐、护理类别的选取规则均不变。水分展示项P现在为自己的水分项,不再伪装为合成分。
|
||||
- 新生成报告与本地原始数据回放使用新文案。历史已保存的presentation文案保留,不批量改写文件;如需纠正历史报告展示,应另行确定范围。
|
||||
|
||||
参考文案与生成文件同步修改。water-copy.js覆盖真实矛盾值、80/90边界、色素不影响水分文案、严重度条件、交叉校验、缺失和输入不变;复测报告持久化、账号隔离、推荐与肤色文案。
|
||||
@@ -0,0 +1,19 @@
|
||||
# 透亮感改为三项独立最低分
|
||||
|
||||
用户确认方案2:透亮感百分制P=min(独立肤色项,水分项,平滑度项),缺项剔除,三项全缺失则不评分。十分制沿用7+3×P/100、显示范围7~10、内部保留两位小数。综合得分仍按紧塑力4、透亮感3、稳韧力3四舍五入取整数。
|
||||
|
||||
独立肤色项继续使用色素扣斑后80%+黑眼圈20%;水分保留已有缺水交叉校验。新透亮感参与原有优先关注及肤龄边界产品推荐判断,未另改推荐规则。
|
||||
|
||||
为兼容旧文案、旧六分类接口及历史记录,cats.tone和旧版统计字段暂时保留。旧平均分不再进入新版透亮感、综合得分、优先关注、产品推荐或七项护理选择。正式报告使用七项展示,后台新记录新增sub_scores七项独立评分,并记录vita_score_rule=independent-color-water-smooth-min-v1;历史记录仍标注历史六分类,不以新版重算历史评分或推荐。
|
||||
|
||||
本次上线包括已确认的独立肤色/水分文案、七选三且关注优先的护理建议,以及产品标题恢复14.467593px/灰色副标题同比放大。三图轮播仍是本地试验,不纳入正式页面,不上传真实案例数据或私有预览脚本。
|
||||
|
||||
## 真实案例回放(当前规则)
|
||||
|
||||
|案例|旧透亮感S|新透亮感S|旧总分|新总分|推荐变化|
|
||||
|---|---:|---:|---:|---:|---|
|
||||
|R20261014-171911-O6YJ|9.26|9.09|88|88|仍25+|
|
||||
|R20261015-111214-JKNS|9.34|8.76|94|93|仍25+|
|
||||
|R20261014-171215-CYLF|9.63|9.63|94|94|仍25+|
|
||||
|
||||
JKNS优先关注由紧塑力变为透亮感,护理建议顺序变为肤色→平滑度→皱纹,符合关注项前置要求。测试仅回放现有返回,未重新调用付费检测。
|
||||
@@ -14,7 +14,7 @@
|
||||
"12": "server.js",
|
||||
"13": "files",
|
||||
"14": "showScreen",
|
||||
"15": "TinyYolov2",
|
||||
"15": "height",
|
||||
"16": "巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范",
|
||||
"17": "extractFaces",
|
||||
"18": "1'me肌肤状态检测 H5",
|
||||
@@ -25,7 +25,7 @@
|
||||
"23": "facepp-skinanalyze(旷视皮肤分析专业版调用技能)",
|
||||
"24": "巨子测肤 · 1'me 语音播报内容设计文档 V1.0",
|
||||
"25": "mobile-select.iife.min.js",
|
||||
"26": "NeuralNetwork",
|
||||
"26": "extractWeightsFactory",
|
||||
"27": "gen_voice.py",
|
||||
"28": "C",
|
||||
"29": "face-api.js 本地化依赖(h5/vendor/faceapi/)",
|
||||
@@ -37,16 +37,16 @@
|
||||
"35": "customer-feedback.js",
|
||||
"36": "actualFont",
|
||||
"37": "UI 外发版 10.09 图片资源",
|
||||
"38": "customer-feedback-fourth.mjs",
|
||||
"38": "FaceProcessor",
|
||||
"39": "UI交互界面调整",
|
||||
"40": "第四轮反馈修改与验收",
|
||||
"41": "js/beijing-time.js",
|
||||
"42": "layer_at",
|
||||
"43": "extractAllFacesAndComputeResults",
|
||||
"44": "start-local.sh",
|
||||
"45": "head-pose.js",
|
||||
"46": ".forwardInput",
|
||||
"47": ".toString",
|
||||
"45": "NeuralNetwork",
|
||||
"46": ".toString",
|
||||
"47": "convLayer",
|
||||
"48": "已修改",
|
||||
"49": "mobile-select/README.md",
|
||||
"50": "call_skinanalyze_3view.sh",
|
||||
@@ -65,7 +65,7 @@
|
||||
"63": "e2e-browser.mjs",
|
||||
"64": "综合得分:三维度按 4:3:3 加权",
|
||||
"65": "微信登录接入与公网部署说明",
|
||||
"66": "h5/README.md",
|
||||
"66": "七项护理选三与关注优先",
|
||||
"67": "ui-20261009.mjs",
|
||||
"68": "analyze-timeout.js",
|
||||
"69": "misans/README.md",
|
||||
@@ -73,11 +73,11 @@
|
||||
"71": "报告顶部评分与年龄排版",
|
||||
"72": "build_report_copy.py",
|
||||
"73": "camera-geometry.js",
|
||||
"74": "report-copy.js",
|
||||
"74": "water-copy.js",
|
||||
"75": "prepare_h5_assets.py",
|
||||
"76": "报告页滑动防冲突-2026-10-13.md",
|
||||
"77": "vizCompose",
|
||||
"78": "height",
|
||||
"77": "care-selection.js",
|
||||
"78": "FaceFeatureExtractor",
|
||||
"79": "登录反馈与加载优化(2026-10-12)",
|
||||
"80": "线上微信登录部署记录",
|
||||
"81": "wechat-production.mjs",
|
||||
@@ -90,23 +90,23 @@
|
||||
"88": "ui-20261012/manifest.json",
|
||||
"89": "傅艳NEW与项思炼的会话 2026年10月12日.md",
|
||||
"90": "customer-feedback.mjs",
|
||||
"91": "wi",
|
||||
"91": ".extractWeights",
|
||||
"92": "客户反馈修改(2026-10-12)",
|
||||
"93": "capture-diagnostics.js",
|
||||
"93": "TinyXception",
|
||||
"94": "第三轮反馈:PSD 对齐、验收及上线记录",
|
||||
"95": "recommendation.js",
|
||||
"95": ".forwardInput",
|
||||
"96": "i",
|
||||
"97": "account-client.js",
|
||||
"98": "drawFaceExpressions",
|
||||
"99": "normalize",
|
||||
"98": ".runAndExtendWithFaceDetections",
|
||||
"99": ".div",
|
||||
"100": ".runAndExtendWithFaceDetection",
|
||||
"101": "wechat-fixture.cjs",
|
||||
"102": "report-persistence.mjs",
|
||||
"102": "TinyFaceFeatureExtractor",
|
||||
"103": "第四轮反馈/傅艳NEW与项思炼的会话 2026年10月12日.md",
|
||||
"104": "export_fourth_feedback_assets.py",
|
||||
"105": "capture-quality-browser.mjs",
|
||||
"106": "第三轮反馈20261012/傅艳NEW与项思炼的会话 2026年10月12日.md",
|
||||
"107": "基础信息记忆与肤质拖动",
|
||||
"107": "h5/README.md",
|
||||
"108": "profile-interaction.mjs",
|
||||
"109": "submitPhotos",
|
||||
"110": "startCamera",
|
||||
@@ -115,11 +115,11 @@
|
||||
"113": "swipe-track.js",
|
||||
"114": "optimize_delivery_images.py",
|
||||
"115": "痘痘按三视图各类型最大数量计分",
|
||||
"116": "age",
|
||||
"117": ".runAndExtendWithFaceDetections",
|
||||
"116": ".predictAgeAndGender",
|
||||
"117": "normalize",
|
||||
"118": "f",
|
||||
"119": "肤色文案与实际黑眼圈等级-2026-10-14.md",
|
||||
"120": "AgeGenderNet",
|
||||
"120": "disposeUnusedWeightTensors",
|
||||
"121": ".draw",
|
||||
"122": "doCapture",
|
||||
"123": "评分圈内居中、基础信息页固定与正脸语音修复",
|
||||
@@ -132,20 +132,30 @@
|
||||
"130": "wrinkle-overall.js",
|
||||
"131": "原始肌龄显示与鸿蒙滚轮兼容",
|
||||
"132": "harmony-picker.mjs",
|
||||
"133": "FaceLandmarks68",
|
||||
"133": "onDetect",
|
||||
"134": "camera-flip-browser.mjs",
|
||||
"135": "恢复321与色斑案例复测",
|
||||
"136": "js/profile-store.js",
|
||||
"136": "age",
|
||||
"137": "皱纹改用接口整体评分",
|
||||
"138": "DetectSingleFaceLandmarksTask",
|
||||
"139": ".mul",
|
||||
"139": "private-case-preview.mjs",
|
||||
"140": "AgeGenderNet",
|
||||
"141": "start",
|
||||
"142": "tone-dark-circle.js",
|
||||
"143": "recommendation.js",
|
||||
"144": "肤色项加入黑眼圈20%,色素图30%叠加",
|
||||
"145": "PredictAllAgeAndGenderWithFaceAlignmentTask",
|
||||
"146": "FaceLandmark68Net",
|
||||
"147": "拍摄角度不合格震动提醒-2026-10-13.md",
|
||||
"148": "PredictAllFaceExpressionsWithFaceAlignmentTask",
|
||||
"149": "PredictSingleAgeAndGenderWithFaceAlignmentTask",
|
||||
"150": "PredictSingleFaceExpressionsWithFaceAlignmentTask",
|
||||
"153": "tone-overlay-browser.mjs"
|
||||
"149": "report-persistence.mjs",
|
||||
"150": ".forwardInput",
|
||||
"151": "FaceRecognitionNet",
|
||||
"152": "FaceExpressionNet",
|
||||
"153": "tone-overlay-browser.mjs",
|
||||
"154": "wi",
|
||||
"155": "游客不留存与弹窗护理间距调整",
|
||||
"156": "FaceLandmarks68",
|
||||
"157": "水分文案独立分档",
|
||||
"158": "drawFaceExpressions"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"0": "aa59fd8abc2eee29", "1": "cb6ea50bd4e4a5ca", "2": "fb3668625bb1d5ad", "3": "5bfb236350c342ee", "4": "4b1835ae3a82cf12", "5": "612f79173cb2d3b8", "6": "4b54405c5a282677", "7": "03b56b13a08b5f83", "8": "3d958eb3ed2a04df", "9": "e8cd0b51895b5f82", "10": "100a78535c7a8861", "11": "8fe2f9d63516be5c", "12": "cba798df74f6df27", "13": "7e3b558a587a4ebe", "14": "58417b287cc79e90", "15": "c96276581a8c98d4", "16": "95add6a975c0cb72", "17": "c25de97209f4e69b", "18": "f93d5d85e671fcee", "19": "76557988bbebbed8", "20": "aecf2fce44ba49c5", "21": "f4675fc43b3461fa", "22": "44afcd0daafd8e6d", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "46e8db3e6e3f37ea", "26": "18ffa2c1feddfd10", "27": "eab427ce9a5219e9", "28": "b0aaa80168ccc897", "29": "c608f1c6492e1cb1", "30": "73c13793fca09f56", "31": "fbbcfc059751cc6a", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "241be5abeab1da6f", "36": "a7d375041779bad4", "37": "cb8f26249485324a", "38": "fbc8a72e6fda6359", "39": "fdd95375b4a5ddb3", "40": "5e546676ab96de03", "41": "a7a205c1adc39fe5", "42": "916170b9f5d7346b", "43": "ebf7b8a48916906e", "44": "852c1bb2446edd9c", "45": "0a373ad2197fd1a6", "46": "880a74c6d255e5cc", "47": "89e609b2678905d3", "48": "cf2f2424bc00436f", "49": "1f976711cda158dc", "50": "bbb2b57d72922b16", "51": "eb6a182204867275", "52": "2ec3c8c088568ba9", "53": "68c45056378341a7", "54": "c58d41e8e580fdc6", "55": "812950f51be20e40", "56": "c92bed61fc5b4cff", "57": "f2a40b5f1b29f669", "58": "08503e12d10e51b8", "59": "891f59cda3708718", "60": "a505b7de6257a4e8", "61": "5209ce2a267bf33b", "62": "1366ae24c7e5897d", "63": "c256b43f75d7809e", "64": "ad47fc38e493a4e2", "65": "bdee3c4a37df52f8", "66": "9727b30d720298e3", "67": "3e126d8deaf6e200", "68": "6b91f3679541de79", "69": "e511846eeba03076", "70": "be0c8310abda2467", "71": "589a2d5a76f3880a", "72": "c84f196a7bd35861", "73": "2b887bf601ccfb9f", "74": "ae2a154311e1f53a", "75": "69fdd23278518884", "76": "3c4c278d6026bc3a", "77": "288c2a98831b0021", "78": "aef6e0c179bd709d", "79": "c6cfdfe181232ecc", "80": "315325cde1352e98", "81": "37c559741825be74", "82": "200f25fbad7af8fb", "83": "1284897282eb47a3", "84": "d8bb296741d3d05c", "85": "7067e88534a91ab4", "86": "386c6fcc7be918e0", "87": "e5fa7717989eda80", "88": "8b5ab5232cef3457", "89": "9e3363b80eeceeea", "90": "dd1c246e19a2d032", "91": "83b0fd3b14363e4d", "92": "fced244d93677d90", "93": "9380a89a868c76d2", "94": "713d04996c4627df", "95": "e594ecaa8e7d1538", "96": "33b6c8b6c3ddaa73", "97": "505ea719b994ac5e", "98": "979dcc63399620ad", "99": "fbe2db75dbd18147", "100": "5a9014c4a7f87699", "101": "beb276de6301634c", "102": "e042d7fe7351bcb9", "103": "6ffbe07b521a061b", "104": "e114a7aebaaca2f1", "105": "af50c66d16c81bba", "106": "8bc72c179793e1c2", "107": "3877490226a78145", "108": "e0fc0a42e33bda91", "109": "4f73a56ac12b2cb5", "110": "cc7d97493f18fe9d", "111": "e8542da06408ad18", "112": "af995dd35403b4dd", "113": "0d99f86b9e41c4bb", "114": "b9d7c266afa84437", "115": "97af8c753c8d6322", "116": "388846e100846dbe", "117": "46204fb2e4d50c53", "118": "f5fa3e3d7d829c42", "119": "7485900c7157ebbd", "120": "711f3cc04ab3bf23", "121": "bf75bfc99d4f9e34", "122": "4f6d51a884cc3f06", "123": "b091e3eb82b456eb", "124": "df789af52163282e", "125": "e4f29216745ec758", "126": "d32da0afe8e66daa", "127": "006218e34885dbe0", "128": "1c2b248bd950f405", "129": "d52cfabd73e7593c", "130": "d724edff31ad0cb8", "131": "482dbb7ec33d8c23", "132": "3daacabc5062b554", "133": "ac00532d5d77886f", "134": "e7c90d6ef8276a1e", "135": "977cfc41f0c4b0b1", "136": "9b1cf1985223f90a", "137": "2e16ad304d257483", "138": "23f1d406f6c779ae", "139": "e6ef8c2f1b997e99", "142": "d1f85bf935ee51b4", "144": "cb06127f3461dec5", "145": "92ab3e5134ed8685", "146": "9a25b1230b5fe649", "147": "0e6cad06ebfcfb29", "148": "65718282b3c32109", "149": "01f68dfc34a29d32", "150": "8c471c7baeaaca54", "153": "23e1e56f6367f19e"}
|
||||
{"0": "b79045c703a85f80", "1": "cb6ea50bd4e4a5ca", "2": "f87f9b389e268d5a", "3": "abf3aa1189cf8f1c", "4": "4b1835ae3a82cf12", "5": "32f813d0aff62d5d", "6": "4b54405c5a282677", "7": "03b56b13a08b5f83", "8": "3d958eb3ed2a04df", "9": "64a6935321c48bb6", "10": "bde8faf00828ab0a", "11": "8fe2f9d63516be5c", "12": "cba798df74f6df27", "13": "7e3b558a587a4ebe", "14": "767b88826fe02948", "15": "afdd5c2f54c40808", "16": "95add6a975c0cb72", "17": "139ebf070fc2a645", "18": "f93d5d85e671fcee", "19": "5272556cf61d08b3", "20": "aecf2fce44ba49c5", "21": "f4675fc43b3461fa", "22": "44afcd0daafd8e6d", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "46e8db3e6e3f37ea", "26": "22869a4c94306e7b", "27": "eab427ce9a5219e9", "28": "832065bed4246769", "29": "c608f1c6492e1cb1", "30": "73c13793fca09f56", "31": "fbbcfc059751cc6a", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "241be5abeab1da6f", "36": "a7d375041779bad4", "37": "cb8f26249485324a", "38": "57344ed1fd5c260f", "39": "fdd95375b4a5ddb3", "40": "5e546676ab96de03", "41": "a7a205c1adc39fe5", "42": "916170b9f5d7346b", "43": "ebf7b8a48916906e", "44": "852c1bb2446edd9c", "45": "d96493a5f110bd4c", "46": "71f300fdfae6e5a6", "47": "8616cd6d33fcb6cb", "48": "cf2f2424bc00436f", "49": "1f976711cda158dc", "50": "bbb2b57d72922b16", "51": "eb6a182204867275", "52": "2ec3c8c088568ba9", "53": "68c45056378341a7", "54": "c58d41e8e580fdc6", "55": "812950f51be20e40", "56": "c92bed61fc5b4cff", "57": "f2a40b5f1b29f669", "58": "51036d6897035852", "59": "891f59cda3708718", "60": "a505b7de6257a4e8", "61": "5209ce2a267bf33b", "62": "1366ae24c7e5897d", "63": "c256b43f75d7809e", "64": "ad47fc38e493a4e2", "65": "bdee3c4a37df52f8", "66": "204c034e5abd63d5", "67": "3e126d8deaf6e200", "68": "6b91f3679541de79", "69": "e511846eeba03076", "70": "be0c8310abda2467", "71": "589a2d5a76f3880a", "72": "c84f196a7bd35861", "73": "2b887bf601ccfb9f", "74": "98e5dfa159a96c21", "75": "69fdd23278518884", "76": "3c4c278d6026bc3a", "77": "5bcfd82487d3f96b", "78": "a7d08d05c6f6461e", "79": "fe1396c4b34beeea", "80": "059d6ba8ca7ec3a0", "81": "37c559741825be74", "82": "200f25fbad7af8fb", "83": "1284897282eb47a3", "84": "d8bb296741d3d05c", "85": "7067e88534a91ab4", "86": "386c6fcc7be918e0", "87": "e5fa7717989eda80", "88": "8b5ab5232cef3457", "89": "9e3363b80eeceeea", "90": "dd1c246e19a2d032", "91": "9f638135a00ee9e5", "92": "fced244d93677d90", "93": "9beb9113cf6685a2", "94": "713d04996c4627df", "95": "880a74c6d255e5cc", "96": "54d7329fed675057", "97": "505ea719b994ac5e", "98": "f45aa61f1a2036bf", "99": "7ae4bb2556c18db2", "100": "5a9014c4a7f87699", "101": "beb276de6301634c", "102": "ec24a95b0cbd8486", "103": "6ffbe07b521a061b", "104": "e114a7aebaaca2f1", "105": "af50c66d16c81bba", "106": "8bc72c179793e1c2", "107": "62b55366408c54b3", "108": "e0fc0a42e33bda91", "109": "4afb1715f62865b1", "110": "e934052f1818c730", "111": "e8542da06408ad18", "112": "af995dd35403b4dd", "113": "0d99f86b9e41c4bb", "114": "b9d7c266afa84437", "115": "97af8c753c8d6322", "116": "a2b13160223b5a98", "117": "cc7621a6b501b8a2", "118": "64fc48534d3085ad", "119": "7485900c7157ebbd", "120": "f58b0adffbac7bf5", "121": "bf75bfc99d4f9e34", "122": "0552b1fe9ffd0332", "123": "b091e3eb82b456eb", "124": "df789af52163282e", "125": "e4f29216745ec758", "126": "d32da0afe8e66daa", "127": "006218e34885dbe0", "128": "1c2b248bd950f405", "129": "d52cfabd73e7593c", "130": "d724edff31ad0cb8", "131": "482dbb7ec33d8c23", "132": "3daacabc5062b554", "133": "d4869eb40daf536c", "134": "e7c90d6ef8276a1e", "135": "977cfc41f0c4b0b1", "136": "480b285d17853682", "137": "2e16ad304d257483", "138": "23f1d406f6c779ae", "139": "c5fa096607dfdbfa", "140": "14fdf4e4c496519f", "141": "a01bccd7f7c24c78", "142": "d1f85bf935ee51b4", "143": "e594ecaa8e7d1538", "144": "cb06127f3461dec5", "145": "92ab3e5134ed8685", "146": "9a25b1230b5fe649", "147": "0e6cad06ebfcfb29", "148": "624ff2146c7868e4", "149": "e042d7fe7351bcb9", "150": "15f58f7494ac2b87", "151": "b186b90877868930", "152": "e858d75e995c92e5", "153": "23e1e56f6367f19e", "154": "83b0fd3b14363e4d", "155": "8cd80516c6c469f5", "156": "68c52c80f38f8b2c", "157": "de7d5f558c2eaf13", "158": "a0bc88eb14b70170"}
|
||||
+170
-127
@@ -1,16 +1,16 @@
|
||||
# Graph Report - juzi (2026-10-15)
|
||||
|
||||
## Corpus Check
|
||||
- 140 files · ~4,961,406 words
|
||||
- 147 files · ~5,059,946 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 1631 nodes · 3106 edges · 149 communities (119 shown, 30 thin omitted)
|
||||
- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 215 edges (avg confidence: 0.57)
|
||||
- 1670 nodes · 3158 edges · 159 communities (126 shown, 33 thin omitted)
|
||||
- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 222 edges (avg confidence: 0.58)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `60ae6c97`
|
||||
- Built from commit: `77493bdf`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
- server.js
|
||||
- files
|
||||
- showScreen
|
||||
- TinyYolov2
|
||||
- height
|
||||
- 巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范
|
||||
- extractFaces
|
||||
- 1'me肌肤状态检测 H5
|
||||
@@ -40,7 +40,7 @@
|
||||
- facepp-skinanalyze(旷视皮肤分析专业版调用技能)
|
||||
- 巨子测肤 · 1'me 语音播报内容设计文档 V1.0
|
||||
- mobile-select.iife.min.js
|
||||
- NeuralNetwork
|
||||
- extractWeightsFactory
|
||||
- gen_voice.py
|
||||
- C
|
||||
- face-api.js 本地化依赖(h5/vendor/faceapi/)
|
||||
@@ -50,16 +50,16 @@
|
||||
- build-fixture.py
|
||||
- customer-feedback.js
|
||||
- UI 外发版 10.09 图片资源
|
||||
- customer-feedback-fourth.mjs
|
||||
- FaceProcessor
|
||||
- UI交互界面调整
|
||||
- 第四轮反馈修改与验收
|
||||
- js/beijing-time.js
|
||||
- layer_at
|
||||
- extractAllFacesAndComputeResults
|
||||
- start-local.sh
|
||||
- head-pose.js
|
||||
- .forwardInput
|
||||
- NeuralNetwork
|
||||
- .toString
|
||||
- convLayer
|
||||
- 已修改
|
||||
- mobile-select/README.md
|
||||
- call_skinanalyze_3view.sh
|
||||
@@ -75,16 +75,17 @@
|
||||
- e2e-browser.mjs
|
||||
- 综合得分:三维度按 4:3:3 加权
|
||||
- 微信登录接入与公网部署说明
|
||||
- h5/README.md
|
||||
- 七项护理选三与关注优先
|
||||
- ui-20261009.mjs
|
||||
- analyze-timeout.js
|
||||
- misans/README.md
|
||||
- scan-placeholder.mjs
|
||||
- 报告顶部评分与年龄排版
|
||||
- build_report_copy.py
|
||||
- water-copy.js
|
||||
- 报告页滑动防冲突-2026-10-13.md
|
||||
- vizCompose
|
||||
- height
|
||||
- care-selection.js
|
||||
- FaceFeatureExtractor
|
||||
- 登录反馈与加载优化(2026-10-12)
|
||||
- 线上微信登录部署记录
|
||||
- wechat-production.mjs
|
||||
@@ -96,32 +97,32 @@
|
||||
- 产品推荐规则:肤龄基准与边界调整
|
||||
- ui-20261012/manifest.json
|
||||
- 傅艳NEW与项思炼的会话 2026年10月12日.md
|
||||
- wi
|
||||
- .extractWeights
|
||||
- 客户反馈修改(2026-10-12)
|
||||
- capture-diagnostics.js
|
||||
- TinyXception
|
||||
- 第三轮反馈:PSD 对齐、验收及上线记录
|
||||
- recommendation.js
|
||||
- .forwardInput
|
||||
- i
|
||||
- account-client.js
|
||||
- drawFaceExpressions
|
||||
- normalize
|
||||
- .runAndExtendWithFaceDetections
|
||||
- .div
|
||||
- .runAndExtendWithFaceDetection
|
||||
- wechat-fixture.cjs
|
||||
- report-persistence.mjs
|
||||
- TinyFaceFeatureExtractor
|
||||
- 第四轮反馈/傅艳NEW与项思炼的会话 2026年10月12日.md
|
||||
- 第三轮反馈20261012/傅艳NEW与项思炼的会话 2026年10月12日.md
|
||||
- 基础信息记忆与肤质拖动
|
||||
- h5/README.md
|
||||
- profile-interaction.mjs
|
||||
- submitPhotos
|
||||
- startCamera
|
||||
- color-copy.js
|
||||
- 微信退出登录-2026-10-13.md
|
||||
- 痘痘按三视图各类型最大数量计分
|
||||
- age
|
||||
- .runAndExtendWithFaceDetections
|
||||
- .predictAgeAndGender
|
||||
- normalize
|
||||
- f
|
||||
- 肤色文案与实际黑眼圈等级-2026-10-14.md
|
||||
- AgeGenderNet
|
||||
- disposeUnusedWeightTensors
|
||||
- .draw
|
||||
- doCapture
|
||||
- 评分圈内居中、基础信息页固定与正脸语音修复
|
||||
@@ -133,20 +134,30 @@
|
||||
- wrinkle-overall.js
|
||||
- 原始肌龄显示与鸿蒙滚轮兼容
|
||||
- harmony-picker.mjs
|
||||
- FaceLandmarks68
|
||||
- onDetect
|
||||
- 恢复321与色斑案例复测
|
||||
- js/profile-store.js
|
||||
- age
|
||||
- 皱纹改用接口整体评分
|
||||
- DetectSingleFaceLandmarksTask
|
||||
- .mul
|
||||
- private-case-preview.mjs
|
||||
- AgeGenderNet
|
||||
- start
|
||||
- tone-dark-circle.js
|
||||
- recommendation.js
|
||||
- 肤色项加入黑眼圈20%,色素图30%叠加
|
||||
- PredictAllAgeAndGenderWithFaceAlignmentTask
|
||||
- FaceLandmark68Net
|
||||
- 拍摄角度不合格震动提醒-2026-10-13.md
|
||||
- PredictAllFaceExpressionsWithFaceAlignmentTask
|
||||
- PredictSingleAgeAndGenderWithFaceAlignmentTask
|
||||
- PredictSingleFaceExpressionsWithFaceAlignmentTask
|
||||
- report-persistence.mjs
|
||||
- .forwardInput
|
||||
- FaceRecognitionNet
|
||||
- FaceExpressionNet
|
||||
- wi
|
||||
- 游客不留存与弹窗护理间距调整
|
||||
- FaceLandmarks68
|
||||
- 水分文案独立分档
|
||||
- drawFaceExpressions
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `__awaiter()` - 59 edges
|
||||
@@ -175,31 +186,31 @@
|
||||
## Import Cycles
|
||||
- None detected.
|
||||
|
||||
## Communities (149 total, 30 thin omitted)
|
||||
## Communities (159 total, 33 thin omitted)
|
||||
|
||||
### Community 0 - "face-api.js"
|
||||
Cohesion: 0.02
|
||||
Nodes (37): bgrToRgbTensor(), cn(), computeReshapedDimensions(), createBrowserEnv(), createFileSystem(), createNodejsEnv(), Dimensions(), dr() (+29 more)
|
||||
Nodes (39): cn(), computeReshapedDimensions(), createBrowserEnv(), createFileSystem(), createNodejsEnv(), Dimensions(), dr(), en() (+31 more)
|
||||
|
||||
### Community 1 - "线上闭环测试(不含真实微信授权)"
|
||||
Cohesion: 0.25
|
||||
Nodes (7): 发现并修复, 可复现命令, 已通过的检查, 线上闭环测试(不含真实微信授权), 结论, 话术及仓库同步, 验证边界
|
||||
|
||||
### Community 2 - "app.js"
|
||||
Cohesion: 0.12
|
||||
Nodes (19): applyMirror(), cancelSkinDrag(), decode(), drain(), effMirror(), goSkin(), load(), loginAllowed() (+11 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (22): applyMirror(), cancelSkinDrag(), effMirror(), esc(), goSkin(), loginAllowed(), loginWechat(), openHistory() (+14 more)
|
||||
|
||||
### Community 3 - "skin-score.js"
|
||||
Cohesion: 0.07
|
||||
Nodes (59): acneGrade(), buildViewModel(), calcAcne(), calcContour(), calcSens(), calcSmooth(), calcTone(), calcWrinkles() (+51 more)
|
||||
Nodes (63): acneGrade(), buildViewModel(), calcAcne(), calcContour(), calcSens(), calcSmooth(), calcTone(), calcWrinkles() (+55 more)
|
||||
|
||||
### Community 4 - "customer-feedback-second.js"
|
||||
Cohesion: 0.14
|
||||
Nodes (11): assert, context, events, face, fs, geometry, original, path (+3 more)
|
||||
|
||||
### Community 5 - "extractFaceTensors"
|
||||
Cohesion: 0.10
|
||||
Nodes (12): Box(), DetectAllFaceLandmarksTask(), extendWithFaceDetection(), extendWithFaceLandmarks(), extractFaceTensors(), FaceLandmarks(), isTensor3D(), isWithFaceDetection() (+4 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (8): bgrToRgbTensor(), Box(), DetectAllFaceLandmarksTask(), extendWithFaceLandmarks(), extractFaceTensors(), FaceLandmarks(), minBbox(), ObjectDetection()
|
||||
|
||||
### Community 7 - "test/profile-store.js"
|
||||
Cohesion: 0.14
|
||||
@@ -210,12 +221,12 @@ Cohesion: 0.19
|
||||
Nodes (31): ageText(), api(), bind(), captureQualityHtml(), closeDetail(), collectFilters(), dimsHtml(), doRetry() (+23 more)
|
||||
|
||||
### Community 9 - "__awaiter"
|
||||
Cohesion: 0.10
|
||||
Nodes (17): __awaiter(), ComposableTask(), FaceRecognitionNet(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow(), __generator() (+9 more)
|
||||
Cohesion: 0.14
|
||||
Nodes (13): __awaiter(), bufferToImage(), ComposableTask(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow(), __generator() (+5 more)
|
||||
|
||||
### Community 10 - "n"
|
||||
Cohesion: 0.11
|
||||
Nodes (38): ae(), be(), bf(), bi(), ce(), de(), e(), Ef() (+30 more)
|
||||
Cohesion: 0.12
|
||||
Nodes (36): ae(), be(), bf(), bi(), ce(), de(), e(), Ef() (+28 more)
|
||||
|
||||
### Community 11 - "lib/accounts.js"
|
||||
Cohesion: 0.06
|
||||
@@ -230,24 +241,28 @@ Cohesion: 0.12
|
||||
Nodes (15): files, analyze-fail, analyzing, countdown-321, hint-far, hint-front, hint-hold, hint-near (+7 more)
|
||||
|
||||
### Community 14 - "showScreen"
|
||||
Cohesion: 0.27
|
||||
Nodes (10): enterGuest(), loadAppFont(), loginSucceeded(), logoutWechat(), openOverlay(), prepareScanArtwork(), renderAccountStatus(), resetReport() (+2 more)
|
||||
Cohesion: 0.19
|
||||
Nodes (13): enterGuest(), loadAppFont(), loginSucceeded(), logoutWechat(), openOverlay(), prepareScanArtwork(), renderAccountStatus(), resetReport() (+5 more)
|
||||
|
||||
### Community 15 - "height"
|
||||
Cohesion: 0.24
|
||||
Nodes (6): height(), FaceLandmark68NetBase(), getSizesForScale(), normalize$1(), rescaleAndNormalize(), TinyYolov2Base()
|
||||
|
||||
### Community 16 - "巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范"
|
||||
Cohesion: 0.15
|
||||
Nodes (12): 1. 基准与尺寸换算, 2. 色彩规范, 3. 字体规范, 4. 组件切图(assets/svg/), 5. 图片素材(assets/images/,共 15 张), 6. 页面清单(design/ 下有整屏 PNG 预览), 7. 目录结构, 8. 还原建议 (+4 more)
|
||||
|
||||
### Community 17 - "extractFaces"
|
||||
Cohesion: 0.21
|
||||
Nodes (17): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), extractFaces(), extractImagePatches(), getContext2dOrThrow(), getEnv() (+9 more)
|
||||
Cohesion: 0.20
|
||||
Nodes (18): awaitMediaLoaded(), createCanvas(), createCanvasFromMedia(), extractFaces(), extractImagePatches(), getContext2dOrThrow(), getEnv(), getMediaDimensions() (+10 more)
|
||||
|
||||
### Community 18 - "1'me肌肤状态检测 H5"
|
||||
Cohesion: 0.13
|
||||
Nodes (15): 10.09 更新, 1'me肌肤状态检测 H5, Admin API(统一返回 `{ok:false,message}` 错误), Windows 本机部署(提测用), 后台查看(admin.html), 密钥配置, 已知占位清单, 技术说明 (+7 more)
|
||||
|
||||
### Community 19 - "customer-feedback-fourth.js"
|
||||
Cohesion: 0.13
|
||||
Nodes (16): assert, brokenLandmarks, check(), Diagnostics, face(), HeadPose, held, ReportUI (+8 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (38): evaluate(), finite(), assertPoints(), check(), clamp(), dist(), estimate(), makeFrontal() (+30 more)
|
||||
|
||||
### Community 20 - "build_fixtures.py"
|
||||
Cohesion: 0.40
|
||||
@@ -269,9 +284,9 @@ Nodes (8): 1. 音频格式约定(已定), 2. 播报清单(14 条), 3. 播放策
|
||||
Cohesion: 0.20
|
||||
Nodes (16): _arrayLikeToArray(), _arrayWithHoles(), _arrayWithoutHoles(), _classCallCheck(), _createClass(), _defineProperties(), h(), _iterableToArray() (+8 more)
|
||||
|
||||
### Community 26 - "NeuralNetwork"
|
||||
Cohesion: 0.06
|
||||
Nodes (28): createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), extractConvParamsFactory(), extractFCParamsFactory() (+20 more)
|
||||
### Community 26 - "extractWeightsFactory"
|
||||
Cohesion: 0.21
|
||||
Nodes (13): extractConvParamsFactory(), extractFCParamsFactory(), extractorsFactory(), extractorsFactory$1(), extractorsFactory$6(), extractorsFactory$8(), extractParams(), extractParams$1() (+5 more)
|
||||
|
||||
### Community 27 - "gen_voice.py"
|
||||
Cohesion: 0.30
|
||||
@@ -279,7 +294,7 @@ Nodes (11): ndarray, Path, gen_countdown(), main(), normalize_clip(), 倒计时
|
||||
|
||||
### Community 28 - "C"
|
||||
Cohesion: 0.09
|
||||
Nodes (33): ao(), Bo(), C(), cd(), cl(), co(), Do(), eo() (+25 more)
|
||||
Nodes (32): ao(), Bo(), C(), cd(), co(), Do(), eo(), fo() (+24 more)
|
||||
|
||||
### Community 29 - "face-api.js 本地化依赖(h5/vendor/faceapi/)"
|
||||
Cohesion: 0.29
|
||||
@@ -301,10 +316,6 @@ Nodes (27): alternate, approved, assert, crop, details, excellent, fs, model (+1
|
||||
Cohesion: 0.40
|
||||
Nodes (4): UI 外发版 10.09 图片资源, 前端素材对应, 文件位置, 重新导出
|
||||
|
||||
### Community 38 - "customer-feedback-fourth.mjs"
|
||||
Cohesion: 0.20
|
||||
Nodes (8): evaluate(), finite(), CaptureQuality, child, dataRoot, h5, ReportUI, require
|
||||
|
||||
### Community 39 - "UI交互界面调整"
|
||||
Cohesion: 0.40
|
||||
Nodes (4): 1meAI测肤旷视UI问题反馈, UI交互界面调整, 交互, **设计**
|
||||
@@ -329,17 +340,13 @@ Nodes (8): ComputeAllFaceDescriptorsTask(), ComputeSingleFaceDescriptorTask(), e
|
||||
Cohesion: 0.50
|
||||
Nodes (3): HOST, PORT, start-local.sh script
|
||||
|
||||
### Community 45 - "head-pose.js"
|
||||
Cohesion: 0.33
|
||||
Nodes (8): assertPoints(), check(), clamp(), dist(), estimate(), makeFrontal(), makeSide(), midpoint()
|
||||
### Community 46 - ".toString"
|
||||
Cohesion: 0.12
|
||||
Nodes (11): FaceLandmarks5(), FaceMatch(), getCenterPoint(), la(), Point(), pr(), pt(), vt() (+3 more)
|
||||
|
||||
### Community 46 - ".forwardInput"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): boxPredictionLayer(), decodeBoxesLayer(), depthwiseConvLayer(), getCenterCoordinatesAndSizesLayer(), getStridesForLayerIdx(), mobileNetV1(), outputLayer(), pointwiseConvLayer() (+1 more)
|
||||
|
||||
### Community 47 - ".toString"
|
||||
Cohesion: 0.20
|
||||
Nodes (7): FaceLandmarks5(), FaceMatch(), getCenterPoint(), la(), pr(), pt(), vt()
|
||||
### Community 47 - "convLayer"
|
||||
Cohesion: 0.43
|
||||
Nodes (8): convLayer(), fullyConnectedLayer(), ONet(), PNet(), prelu(), qh(), RNet(), sharedLayer()
|
||||
|
||||
### Community 48 - "已修改"
|
||||
Cohesion: 0.22
|
||||
@@ -366,8 +373,8 @@ Cohesion: 0.60
|
||||
Nodes (5): diffCtx(), loadJSON(), main(), okNum(), okStr()
|
||||
|
||||
### Community 58 - ".forwardInput"
|
||||
Cohesion: 0.21
|
||||
Nodes (8): iou(), NetInput(), nonMaxSuppression(), nonMaxSuppression$1(), scale(), stage1(), stage2(), stage3()
|
||||
Cohesion: 0.15
|
||||
Nodes (9): iou(), nonMaxSuppression(), nonMaxSuppression$1(), scale(), SsdMobilenetv1(), stage1(), stage2(), stage3() (+1 more)
|
||||
|
||||
### Community 61 - "报告布局与跟手交互调整"
|
||||
Cohesion: 0.33
|
||||
@@ -389,9 +396,9 @@ Nodes (4): 已确认公式, 本地验证, 生效位置, 综合得分:三维度
|
||||
Cohesion: 0.29
|
||||
Nodes (7): 公网服务器配置, 公网真机验收清单, 反向代理与后台保护, 已完成的链路, 微信登录接入与公网部署说明, 数据、迁移与备份, 本机开发环境限制(不代表线上状态)
|
||||
|
||||
### Community 66 - "h5/README.md"
|
||||
Cohesion: 0.33
|
||||
Nodes (3): 发版范围, 游客不留存与弹窗护理间距调整, 验证
|
||||
### Community 66 - "七项护理选三与关注优先"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 七项护理选三与关注优先, 真实案例回放, 验证
|
||||
|
||||
### Community 68 - "analyze-timeout.js"
|
||||
Cohesion: 0.20
|
||||
@@ -401,20 +408,20 @@ Nodes (7): assert, end, fs, path, source, start, vm
|
||||
Cohesion: 0.29
|
||||
Nodes (3): errors, samples, unexpectedWrites
|
||||
|
||||
### Community 77 - "vizCompose"
|
||||
Cohesion: 0.14
|
||||
Nodes (14): esc(), openHistory(), renderHistoryList(), renderReport(), renderViz(), setDim(), vizCollectMarks(), vizCompose() (+6 more)
|
||||
### Community 74 - "water-copy.js"
|
||||
Cohesion: 0.22
|
||||
Nodes (6): assert, Copy, crossed, example, SS, UI
|
||||
|
||||
### Community 78 - "height"
|
||||
Cohesion: 0.32
|
||||
Nodes (5): height(), FaceLandmark68NetBase(), getSizesForScale(), normalize$1(), rescaleAndNormalize()
|
||||
### Community 77 - "care-selection.js"
|
||||
Cohesion: 0.24
|
||||
Nodes (9): assert, check(), Copy, heavy, keys, sample(), SS, UI (+1 more)
|
||||
|
||||
### Community 79 - "登录反馈与加载优化(2026-10-12)"
|
||||
Cohesion: 0.25
|
||||
Nodes (5): 体验变化, 公网部署后复测, 慢的原因与处理, 登录反馈与加载优化(2026-10-12), 验证
|
||||
|
||||
### Community 80 - "线上微信登录部署记录"
|
||||
Cohesion: 0.33
|
||||
Cohesion: 0.29
|
||||
Nodes (6): 初次部署时的凭据查找记录(现已由用户提供), 初次部署的线上检查(历史结果), 后续更新:已配置真实凭据, 已执行, 用户确认加入白名单后的复测, 线上微信登录部署记录
|
||||
|
||||
### Community 81 - "wechat-production.mjs"
|
||||
@@ -445,41 +452,37 @@ Nodes (6): 产品推荐规则:肤龄基准与边界调整, 决策顺序, 后
|
||||
Cohesion: 0.22
|
||||
Nodes (8): assets, design_scale, document_size, native_header_px, shape_metrics, source, source_sha256, text_styles
|
||||
|
||||
### Community 91 - "wi"
|
||||
Cohesion: 0.28
|
||||
Nodes (9): Ci(), Ei(), Fi(), Ii(), ki(), pe(), ri(), wi() (+1 more)
|
||||
### Community 91 - ".extractWeights"
|
||||
Cohesion: 0.20
|
||||
Nodes (8): createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), extractorsFactory$4(), extractParams$5()
|
||||
|
||||
### Community 92 - "客户反馈修改(2026-10-12)"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): 公网部署与复测, 客户反馈修改(2026-10-12), 皱纹数据说明, 逐项处理, 验证
|
||||
|
||||
### Community 93 - "capture-diagnostics.js"
|
||||
Cohesion: 0.38
|
||||
Nodes (6): assess(), CaptureQuality, HeadPose, normalize(), scalar(), views
|
||||
|
||||
### Community 94 - "第三轮反馈:PSD 对齐、验收及上线记录"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): 原稿与导出可追溯性, 已完成, 本地验证, 生产部署及只读验收, 第三轮反馈:PSD 对齐、验收及上线记录
|
||||
|
||||
### Community 95 - "recommendation.js"
|
||||
Cohesion: 0.33
|
||||
Nodes (6): assert, check(), missing, raw, SS, UI
|
||||
### Community 95 - ".forwardInput"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): boxPredictionLayer(), decodeBoxesLayer(), depthwiseConvLayer(), getCenterCoordinatesAndSizesLayer(), getStridesForLayerIdx(), mobileNetV1(), outputLayer(), pointwiseConvLayer() (+1 more)
|
||||
|
||||
### Community 96 - "i"
|
||||
Cohesion: 0.07
|
||||
Nodes (36): b(), ba(), bn(), ca(), da(), dn(), ee(), et() (+28 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (31): ba(), bn(), ca(), cl(), da(), dn(), ee(), et() (+23 more)
|
||||
|
||||
### Community 97 - "account-client.js"
|
||||
Cohesion: 0.53
|
||||
Nodes (8): browser(), clearGuestCache(), ensureGuest(), guest(), init(), logout(), rememberKind(), request()
|
||||
|
||||
### Community 98 - "drawFaceExpressions"
|
||||
Cohesion: 0.22
|
||||
Nodes (6): DrawBox(), drawDetections(), drawFaceExpressions(), DrawFaceLandmarks(), FaceExpressions(), isWithFaceExpressions()
|
||||
### Community 98 - ".runAndExtendWithFaceDetections"
|
||||
Cohesion: 0.20
|
||||
Nodes (8): DetectAllFacesTask(), DrawBox(), drawDetections(), DrawFaceLandmarks(), extendWithFaceDetection(), isWithFaceDetection(), isWithFaceLandmarks(), resizeResults()
|
||||
|
||||
### Community 99 - "normalize"
|
||||
Cohesion: 0.09
|
||||
Nodes (26): conv(), conv$1(), convDown(), convLayer(), convLayer$1(), convNoRelu(), convWithBatchNorm(), denseBlock3() (+18 more)
|
||||
### Community 99 - ".div"
|
||||
Cohesion: 0.31
|
||||
Nodes (6): conv(), denseBlock3(), denseBlock4(), depthwiseSeparableConv(), mainBlock(), reductionBlock()
|
||||
|
||||
### Community 100 - ".runAndExtendWithFaceDetection"
|
||||
Cohesion: 0.33
|
||||
@@ -489,25 +492,21 @@ Nodes (5): allFacesMtcnn(), allFacesSsdMobilenetv1(), allFacesTinyYolov2(), dete
|
||||
Cohesion: 0.50
|
||||
Nodes (3): crypto, fs, path
|
||||
|
||||
### Community 102 - "report-persistence.mjs"
|
||||
Cohesion: 0.29
|
||||
Nodes (6): child, dataRoot, fx, h5, ReportUI, require
|
||||
|
||||
### Community 107 - "基础信息记忆与肤质拖动"
|
||||
Cohesion: 0.40
|
||||
Nodes (4): 回归命令, 基础信息记忆与肤质拖动, 肤质交互, 范围
|
||||
### Community 107 - "h5/README.md"
|
||||
Cohesion: 0.22
|
||||
Nodes (6): 回归命令, 基础信息记忆与肤质拖动, 肤质交互, 范围, 真实案例回放(当前规则), 透亮感改为三项独立最低分
|
||||
|
||||
### Community 108 - "profile-interaction.mjs"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): dragBy(), h5, touch()
|
||||
|
||||
### Community 109 - "submitPhotos"
|
||||
Cohesion: 0.22
|
||||
Nodes (13): bindBackdropClose(), closeLoginSuccess(), closeOverlay(), handleCamHidden(), leaveCamera(), photosByView(), popHistorySilently(), requestAnalyze() (+5 more)
|
||||
Cohesion: 0.24
|
||||
Nodes (12): bindBackdropClose(), closeLoginSuccess(), closeOverlay(), handleCamHidden(), leaveCamera(), photosByView(), popHistorySilently(), requestAnalyze() (+4 more)
|
||||
|
||||
### Community 110 - "startCamera"
|
||||
Cohesion: 0.22
|
||||
Nodes (13): beginDetect(), detTick(), enableFallback(), getCamStream(), loadFaceApi(), loadModels(), maybeStartDetect(), onCamTrackEnded() (+5 more)
|
||||
Cohesion: 0.17
|
||||
Nodes (16): beginDetect(), detTick(), enableFallback(), getCamStream(), hideCamStatus(), loadFaceApi(), loadModels(), maybeStartDetect() (+8 more)
|
||||
|
||||
### Community 111 - "color-copy.js"
|
||||
Cohesion: 0.25
|
||||
@@ -517,21 +516,25 @@ Nodes (7): assert, descriptions, missing, SS, templates, UI, v
|
||||
Cohesion: 0.40
|
||||
Nodes (4): 后台和历史, 痘痘按三视图各类型最大数量计分, 规则, 验证
|
||||
|
||||
### Community 116 - "age"
|
||||
Cohesion: 0.13
|
||||
Nodes (6): age(), extendWithAge(), extendWithGender(), FaceExpressionNet(), PredictAllAgeAndGenderTask(), PredictSingleAgeAndGenderTask()
|
||||
### Community 116 - ".predictAgeAndGender"
|
||||
Cohesion: 0.28
|
||||
Nodes (4): extendWithAge(), extendWithGender(), PredictAllAgeAndGenderTask(), PredictSingleAgeAndGenderTask()
|
||||
|
||||
### Community 117 - "normalize"
|
||||
Cohesion: 0.36
|
||||
Nodes (8): conv$1(), convDown(), convLayer$1(), convNoRelu(), normalize(), residual(), residualDown(), __spreadArrays()
|
||||
|
||||
### Community 118 - "f"
|
||||
Cohesion: 0.20
|
||||
Nodes (24): a(), cf(), d(), drawContour(), dt(), ea(), f(), g() (+16 more)
|
||||
Cohesion: 0.15
|
||||
Nodes (30): a(), b(), cf(), d(), drawContour(), dt(), ea(), f() (+22 more)
|
||||
|
||||
### Community 120 - "AgeGenderNet"
|
||||
Cohesion: 0.07
|
||||
Nodes (26): AgeGenderNet(), disposeUnusedWeightTensors(), extractorsFactory$3(), extractorsFactory$5(), extractorsFactory$7(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$1() (+18 more)
|
||||
### Community 120 - "disposeUnusedWeightTensors"
|
||||
Cohesion: 0.12
|
||||
Nodes (23): disposeUnusedWeightTensors(), extractorsFactory$3(), extractorsFactory$5(), extractorsFactory$7(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$1(), extractParamsFromWeigthMap$2() (+15 more)
|
||||
|
||||
### Community 122 - "doCapture"
|
||||
Cohesion: 0.14
|
||||
Nodes (27): afterCurrent(), armNudge(), busyWithFlow(), captureFromVideo(), captureHaptic(), captureStageHint(), checkStill(), detectFrame() (+19 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (17): afterCurrent(), armNudge(), busyWithFlow(), captureFromVideo(), captureStageHint(), doCapture(), dropHint(), handleCamVisible() (+9 more)
|
||||
|
||||
### Community 123 - "评分圈内居中、基础信息页固定与正脸语音修复"
|
||||
Cohesion: 0.40
|
||||
@@ -561,44 +564,84 @@ Nodes (6): assert, base, changed, onlyOverall, SS, UI
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 原始肌龄显示与鸿蒙滚轮兼容, 回归, 范围
|
||||
|
||||
### Community 133 - "onDetect"
|
||||
Cohesion: 0.32
|
||||
Nodes (8): captureHaptic(), checkStill(), detectFrame(), faceLuma(), faceOffsetX(), onDetect(), resetAngleHaptic(), updateAngleHaptic()
|
||||
|
||||
### Community 135 - "恢复321与色斑案例复测"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 恢复321与色斑案例复测, 拍摄提示音, 真实色斑案例
|
||||
|
||||
### Community 136 - "js/profile-store.js"
|
||||
Cohesion: 0.67
|
||||
Nodes (3): clean(), create(), key()
|
||||
### Community 136 - "age"
|
||||
Cohesion: 0.36
|
||||
Nodes (4): age(), clean(), create(), key()
|
||||
|
||||
### Community 137 - "皱纹改用接口整体评分"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 案例复算, 皱纹改用接口整体评分, 验证
|
||||
|
||||
### Community 139 - ".mul"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): wl(), wn(), xn()
|
||||
### Community 139 - "private-case-preview.mjs"
|
||||
Cohesion: 0.29
|
||||
Nodes (6): fixture, mime, photos, raw, root, server
|
||||
|
||||
### Community 141 - "start"
|
||||
Cohesion: 0.29
|
||||
Nodes (7): decode(), drain(), load(), preload(), start(), stopCur(), unlock()
|
||||
|
||||
### Community 142 - "tone-dark-circle.js"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): a, assert, near(), SS, UI
|
||||
|
||||
### Community 143 - "recommendation.js"
|
||||
Cohesion: 0.33
|
||||
Nodes (6): assert, check(), missing, raw, SS, UI
|
||||
|
||||
### Community 144 - "肤色项加入黑眼圈20%,色素图30%叠加"
|
||||
Cohesion: 0.40
|
||||
Nodes (4): 图像, 用户确认的评分口径, 肤色项加入黑眼圈20%,色素图30%叠加, 验证
|
||||
|
||||
### Community 148 - "PredictAllFaceExpressionsWithFaceAlignmentTask"
|
||||
Cohesion: 0.17
|
||||
Nodes (3): PredictAllFaceExpressionsWithFaceAlignmentTask(), PredictSingleAgeAndGenderWithFaceAlignmentTask(), PredictSingleFaceExpressionsWithFaceAlignmentTask()
|
||||
|
||||
### Community 149 - "report-persistence.mjs"
|
||||
Cohesion: 0.29
|
||||
Nodes (6): child, dataRoot, fx, h5, ReportUI, require
|
||||
|
||||
### Community 150 - ".forwardInput"
|
||||
Cohesion: 0.47
|
||||
Nodes (3): convWithBatchNorm(), depthwiseSeparableConv$1(), leaky()
|
||||
|
||||
### Community 151 - "FaceRecognitionNet"
|
||||
Cohesion: 0.33
|
||||
Nodes (3): extractorsFactory$2(), extractParams$4(), FaceRecognitionNet()
|
||||
|
||||
### Community 154 - "wi"
|
||||
Cohesion: 0.28
|
||||
Nodes (9): Ci(), Ei(), Fi(), Ii(), ki(), pe(), ri(), wi() (+1 more)
|
||||
|
||||
### Community 155 - "游客不留存与弹窗护理间距调整"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 发版范围, 游客不留存与弹窗护理间距调整, 验证
|
||||
|
||||
### Community 158 - "drawFaceExpressions"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): drawFaceExpressions(), FaceExpressions(), isWithFaceExpressions()
|
||||
|
||||
## Knowledge Gaps
|
||||
- **418 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+413 more)
|
||||
- **441 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+436 more)
|
||||
These have ≤1 connection - possible missing edges or undocumented components.
|
||||
- **30 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||
- **33 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||
|
||||
## Suggested Questions
|
||||
_Questions this graph is uniquely positioned to answer:_
|
||||
|
||||
- **Why does `height()` connect `height` to `app.js`, `customer-feedback.js`, `extractFaceTensors`, `scan-placeholder.mjs`, `__awaiter`, `profile-interaction.mjs`, `showScreen`, `extractFaces`, `.forwardInput`?**
|
||||
_High betweenness centrality (0.053) - this node is a cross-community bridge._
|
||||
- **Why does `height()` connect `height` to `app.js`, `customer-feedback.js`, `extractFaceTensors`, `scan-placeholder.mjs`, `profile-interaction.mjs`, `showScreen`, `extractFaces`, `.forwardInput`?**
|
||||
_High betweenness centrality (0.044) - this node is a cross-community bridge._
|
||||
- **Why does `r()` connect `n` to `face-api.js`, `i`, `server.js`, `.toString`, `normalize`, `f`, `C`?**
|
||||
_High betweenness centrality (0.033) - this node is a cross-community bridge._
|
||||
- **Why does `n()` connect `n` to `face-api.js`, `i`, `skin-score.js`, `server.js`, `acne-three-view.js`, `f`, `C`?**
|
||||
_High betweenness centrality (0.038) - this node is a cross-community bridge._
|
||||
- **Why does `r()` connect `n` to `face-api.js`, `i`, `normalize`, `server.js`, `.toString`, `f`, `C`?**
|
||||
_High betweenness centrality (0.034) - this node is a cross-community bridge._
|
||||
_High betweenness centrality (0.028) - this node is a cross-community bridge._
|
||||
- **Are the 26 inferred relationships involving `n()` (e.g. with `calcAcne()` and `newRecordId()`) actually correct?**
|
||||
_`n()` has 26 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 27 inferred relationships involving `r()` (e.g. with `handleExport()` and `handleRecordsQuery()`) actually correct?**
|
||||
@@ -606,4 +649,4 @@ _Questions this graph is uniquely positioned to answer:_
|
||||
- **Are the 10 inferred relationships involving `i()` (e.g. with `report-persistence.mjs` and `da()`) actually correct?**
|
||||
_`i()` has 10 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **What connects `source`, `document_size`, `pages` to the rest of the system?**
|
||||
_418 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
_441 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
File diff suppressed because one or more lines are too long
+1824
-801
File diff suppressed because it is too large
Load Diff
+81
-26
@@ -50,13 +50,13 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/skin-score.js": {
|
||||
"mtime": 1791992633.3478043,
|
||||
"ast_hash": "13c216059688fd865d236fdfb4e78fd7",
|
||||
"mtime": 1792046332.1885464,
|
||||
"ast_hash": "96afdc807eaf06bd861a39f39ed119df",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/server.js": {
|
||||
"mtime": 1791992633.3478043,
|
||||
"ast_hash": "9006db8d78051713084a8f9e292f594e",
|
||||
"mtime": 1792046437.6590993,
|
||||
"ast_hash": "a7b6deccacb03cff6c0dc6ab9764ae16",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/build_fixtures.py": {
|
||||
@@ -80,8 +80,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/regression.js": {
|
||||
"mtime": 1791991599.1785402,
|
||||
"ast_hash": "8a6ae12fb62288d2bb02655d9c21ade9",
|
||||
"mtime": 1792046332.1885464,
|
||||
"ast_hash": "4c7998dc9962ce109bde7bc29891d538",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/vendor/faceapi/face-api.js": {
|
||||
@@ -135,8 +135,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/README.md": {
|
||||
"mtime": 1791992669.0684593,
|
||||
"ast_hash": "b1eae85ed8ef9cfadd00de923468cbbb",
|
||||
"mtime": 1792046412.3080864,
|
||||
"ast_hash": "5e60028c676088d6e62d373ff94f20c7",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/index.html": {
|
||||
@@ -815,8 +815,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/admin.js": {
|
||||
"mtime": 1791992633.351766,
|
||||
"ast_hash": "7cbc57b137513efef5af59ecc92c3f10",
|
||||
"mtime": 1792046275.1971712,
|
||||
"ast_hash": "339073665d8a01c84d169ca696a108b5",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/region-data.js": {
|
||||
@@ -1240,13 +1240,13 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/report-copy.js": {
|
||||
"mtime": 1791993447.3913798,
|
||||
"ast_hash": "452c90f7bbe8dc3afc842d6ff1a286e2",
|
||||
"mtime": 1792044306.7377708,
|
||||
"ast_hash": "ac8f1225149a88902b2b35476e1258f5",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/report-ui.js": {
|
||||
"mtime": 1791997508.305589,
|
||||
"ast_hash": "ef6df0e12065dfc4d157494891038268",
|
||||
"mtime": 1792044306.7105672,
|
||||
"ast_hash": "866badf68a4534927262c037eec35eca",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/lib/accounts.js": {
|
||||
@@ -1260,8 +1260,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/report-persistence.mjs": {
|
||||
"mtime": 1791992713.7256725,
|
||||
"ast_hash": "904ec9d4daa04b068b972cd9037615bb",
|
||||
"mtime": 1792046332.1885464,
|
||||
"ast_hash": "8f79e7750a0565508e487e1d3b34e6f3",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/ui-20261009.mjs": {
|
||||
@@ -1300,8 +1300,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"reference/AI\u6d4b\u80a4\u62a5\u544a\u9875\u8bdd\u672f\u4fee\u6539.md": {
|
||||
"mtime": 1791993479.4296343,
|
||||
"ast_hash": "fd4e8d0621fb67015be0a150fac32a4c",
|
||||
"mtime": 1792044306.7105672,
|
||||
"ast_hash": "1ecb0769c53f7af44c991ba099359fc6",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"design/ui-20261009/audit-current/01-splash.png": {
|
||||
@@ -2085,8 +2085,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/tone-dark-circle.js": {
|
||||
"mtime": 1791993447.323378,
|
||||
"ast_hash": "16091c603e1bec56af80210946670527",
|
||||
"mtime": 1792046293.4017394,
|
||||
"ast_hash": "2c783245bf43ef7173210418a76de600",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/tone-overlay-browser.mjs": {
|
||||
@@ -2120,8 +2120,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/color-copy.js": {
|
||||
"mtime": 1791993447.3273783,
|
||||
"ast_hash": "4777441d7249d042cb9d48da67ac5c74",
|
||||
"mtime": 1792044306.7105672,
|
||||
"ast_hash": "f1e8ae0f65f1cd17263c171c6435e063",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/\u80a4\u8272\u6587\u6848\u4e0e\u5b9e\u9645\u9ed1\u773c\u5708\u7b49\u7ea7-2026-10-14.md": {
|
||||
@@ -2130,13 +2130,13 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/report-bottom-figma.mjs": {
|
||||
"mtime": 1791998797.7419598,
|
||||
"ast_hash": "81af5b52ef2b0b1d14f9ffb6159f2d3a",
|
||||
"mtime": 1791999287.71825,
|
||||
"ast_hash": "ebde53e93a34e4ed5f877c65af1456b0",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/\u62a5\u544a\u5e95\u90e8Figma\u8fd8\u539f-2026-10-15.md": {
|
||||
"mtime": 1791998656.0611603,
|
||||
"ast_hash": "ce4a94e4026ebc2c410f76f361a24ca1",
|
||||
"mtime": 1791999287.71825,
|
||||
"ast_hash": "b72dae0ed84a076c0d8f99dcebe9bbeb",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/img/ui-20261015/product-25.png": {
|
||||
@@ -2158,5 +2158,60 @@
|
||||
"mtime": 1791997415.2784162,
|
||||
"ast_hash": "4ec7b754fe30aac6248e7f8f990ac078",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/contour-preview.html": {
|
||||
"mtime": 1792045886.5890932,
|
||||
"ast_hash": "a98beeb64d55d5b41969f2312afbe63e",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/mock/contour-demo/front.jpg": {
|
||||
"mtime": 1792033394.649536,
|
||||
"ast_hash": "3b3ba2bbe11175c76f25ea63730106bd",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/mock/contour-demo/left.jpg": {
|
||||
"mtime": 1792033394.6534245,
|
||||
"ast_hash": "af8c5642cfa8b4a4af1f48e4bb02f602",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/mock/contour-demo/right.jpg": {
|
||||
"mtime": 1792033394.6534245,
|
||||
"ast_hash": "65e145520cf438df78b985ddddebe6fd",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/private-case-preview.mjs": {
|
||||
"mtime": 1792034626.0099716,
|
||||
"ast_hash": "b0814e8913316484fbc669f88394a9a5",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/water-copy.js": {
|
||||
"mtime": 1792044368.3417633,
|
||||
"ast_hash": "31ef3ff18bfb9014a35bcb5f2260af28",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/\u6c34\u5206\u6587\u6848\u72ec\u7acb\u5206\u6863-2026-10-15.md": {
|
||||
"mtime": 1792043836.616439,
|
||||
"ast_hash": "66bc24a457dced194579fc9b926f0a26",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/care-selection.js": {
|
||||
"mtime": 1792044368.3456743,
|
||||
"ast_hash": "e84928b11825a219a691f721f1a0590a",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/\u4e03\u9879\u62a4\u7406\u9009\u4e09\u4e0e\u5173\u6ce8\u4f18\u5148-2026-10-15.md": {
|
||||
"mtime": 1792044443.0636487,
|
||||
"ast_hash": "baf56556b9963af9bc77943fcca94989",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/vita-independent.js": {
|
||||
"mtime": 1792046293.397852,
|
||||
"ast_hash": "563dfef2b579cf93aa248f1e49a20ed1",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/\u900f\u4eae\u611f\u6539\u4e3a\u4e09\u9879\u72ec\u7acb\u6700\u4f4e\u5206-2026-10-15.md": {
|
||||
"mtime": 1792046412.3041933,
|
||||
"ast_hash": "48d0853b95e0b36ce79e3f2e3519826f",
|
||||
"semantic_hash": ""
|
||||
}
|
||||
}
|
||||
@@ -134,6 +134,10 @@ node server.js # 默认 8080,可用 PORT=xxx 修改
|
||||
本机浏览器只缓存随机身份凭据,报告保存在服务器;微信需公网 HTTPS、具备网页授权权限的服务号及相应环境变量。
|
||||
详见 [新版实施与验收](../docs/10.09新版H5实施与验收.md) 和 [微信登录接入与公网部署说明](../docs/微信登录接入与公网部署说明.md)。下方旧功能说明以这两份更新文档为准。
|
||||
|
||||
2026-10-15 护理展示更新:`ReportUI.build` 从七项独立小维度分中选最低三项,再将属于当前优先关注大维度的入选项前置;同分按关注优先、文档顺序确定。肤色、水分分析及护理各自独立分档,不再共用肤色水润合成分。新版护理全文以 `reference/AI测肤报告页话术修改.md` 为准;不改变原三维度/综合得分/产品推荐,不批量改写历史presentation。详见 [七项护理选三与关注优先](../docs/七项护理选三与关注优先-2026-10-15.md)。
|
||||
|
||||
随后用户确认取消合成分参与维度计分:透亮感改为独立肤色、水分、平滑度三项P的最低有效值,不再平均肤色和水分。新分数用于总分、优先关注及原有边界推荐判断。后台新记录展示七项独立分数,历史记录不重算;旧tone字段仅为兼容。详见 [新版透亮感公式](../docs/透亮感改为三项独立最低分-2026-10-15.md)。
|
||||
|
||||
## 部署
|
||||
|
||||
需要 Node ≥ 18 运行 `server.js`(负责静态与 API 中转),**不能用纯静态托管**(密钥不能进前端)。
|
||||
|
||||
@@ -97,17 +97,13 @@
|
||||
.report-care-products .prod-card { height:auto; aspect-ratio:945 / 511; }
|
||||
.report-care-products .prod-info { flex-basis:49.100529%; }
|
||||
.report-care-products .prod-scroll { flex-basis:50.899471%; }
|
||||
.report-care-products #product-title { left:8.571429%; top:29.158513%; font-size:13.888889px; line-height:17.340278px; font-weight:700; white-space:nowrap; }
|
||||
.report-care-products .prod-name { left:8.677249%; top:41.095890%; font-size:11.532639px; line-height:14.467593px; font-weight:700; color:#989898; white-space:nowrap; }
|
||||
.report-care-products #product-title { left:8.571429%; top:29.158513%; font-size:14.467593px; line-height:18.062790px; font-weight:700; white-space:nowrap; }
|
||||
.report-care-products .prod-name { left:8.677249%; top:41.095890%; font-size:12.013166px; line-height:15.070408px; font-weight:700; color:#989898; white-space:nowrap; }
|
||||
.report-care-products .prod-badge { left:8.783069%; top:56.751468%; width:10.687831%; }
|
||||
.report-care-products + .report-disclaimer { margin:calc(12.152778 * var(--u)) calc(5.208333 * var(--u)) calc(20 * var(--u)); font-size:7.233681px; line-height:10.127431px; }
|
||||
.dimension-stability-title { font-size:22.106597px; line-height:28.738542px; }
|
||||
.stability-card .dtab-tx { font-size:11.055903px; }
|
||||
.stability-card .ditem-para { font-size:11.574074px; line-height:14.467593px; }
|
||||
@media (max-width:359px) {
|
||||
.report-care-products #product-title { font-size:12px; }
|
||||
.report-care-products .prod-name { font-size:10px; }
|
||||
}
|
||||
|
||||
/* Fourth feedback adds a fast one-second round trip to original PSD pixels.
|
||||
The stage/mask share one contain transform, including short/landscape screens. */
|
||||
|
||||
+6
-5
@@ -418,18 +418,19 @@ function renderDetail(data) {
|
||||
if (r.wrinkle_score_rule === 'api-overall-v1') h += '<p class="sub">皱纹评分直接使用接口整体皱纹分数,不做100减分,也不再按分区严重度限分。</p>';
|
||||
if (r.tone_scoring && r.tone_scoring.version === 'color-dark-circle-20-v1') {
|
||||
var tone = r.tone_scoring;
|
||||
h += '<p class="sub">肤色项=色素扣斑分×80%+黑眼圈评分×20%;再与水分项各占50%。色素扣斑分:' + esc(fmtToneScore(tone.pigment_adjusted_score)) + ',黑眼圈评分:' + esc(fmtToneScore(tone.dark_circle_score)) + ',合成肤色项:' + esc(fmtToneScore(tone.color_score)) + ',水分项:' + esc(fmtToneScore(tone.water_adjusted_score)) + '。缺项按有效权重归一。</p>';
|
||||
h += '<p class="sub">肤色项=色素扣斑分×80%+黑眼圈评分×20%;' + (r.vita_score_rule ? '透亮感取独立肤色、水分、平滑度三项最低分,不再使用肤色水润平均分。' : '历史版本与水分项各占50%。') + '色素扣斑分:' + esc(fmtToneScore(tone.pigment_adjusted_score)) + ',黑眼圈评分:' + esc(fmtToneScore(tone.dark_circle_score)) + ',独立肤色项:' + esc(fmtToneScore(tone.color_score)) + ',水分项:' + esc(fmtToneScore(tone.water_adjusted_score)) + '。肤色缺项按有效权重归一。</p>';
|
||||
}
|
||||
h += '<p class="sub">前端展示肌龄限制在实际年龄±5岁;推荐仍使用原始肌龄。历史报告保留当时的推荐。</p>';
|
||||
|
||||
/* 6 分类表格 */
|
||||
var catRows = '';
|
||||
for (var i = 0; i < CAT_ORDER.length; i++) {
|
||||
var ck = CAT_ORDER[i], cat = r.cats && r.cats[ck];
|
||||
var catName = ({ contour: '轮廓', wrinkles: '皱纹', smooth: '平滑度', tone: '肤色 / 水分', sens: '泛红', acne: '痘痘' })[ck];
|
||||
var scoreOrder = r.sub_scores ? ['contour','wrinkles','color','smooth','water','sens','acne'] : CAT_ORDER;
|
||||
for (var i = 0; i < scoreOrder.length; i++) {
|
||||
var ck = scoreOrder[i], cat = (r.sub_scores || r.cats || {})[ck];
|
||||
var catName = ({ contour: '轮廓', wrinkles: '皱纹', smooth: '平滑度', color:'肤色', water:'水分', tone: '肤色 / 水分(历史)', sens: '泛红', acne: '痘痘' })[ck];
|
||||
catRows += '<tr><td>' + esc(catName) + '</td><td>' + fmtScore(cat && cat.P) + '</td><td>' + fmtScore(cat && cat.S) + '</td><td>' + lvHtml(cat && cat.level) + '</td></tr>';
|
||||
}
|
||||
h += dSec('原始六分类评分(肤色 / 水分共用一项)', '<table class="d-table"><thead><tr><th>分类</th><th>P</th><th>S</th><th>档位</th></tr></thead><tbody>' + catRows + '</tbody></table>');
|
||||
h += dSec(r.sub_scores ? '七项独立评分' : '历史六分类评分(肤色 / 水分共用一项)', '<table class="d-table"><thead><tr><th>分类</th><th>P</th><th>S</th><th>档位</th></tr></thead><tbody>' + catRows + '</tbody></table>');
|
||||
|
||||
/* 3 维度表格 */
|
||||
var dimRows = '';
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"优秀": "肌肤质感表现优异,表面细腻平滑,角质层排列整齐,无明显粗大毛孔与黑头。"
|
||||
},
|
||||
"water": {
|
||||
"改善": "水分分 {water_score};缺水面积 {water_area}%、肌肤缺水比较严重 {water_sev},肌肤含水量偏低,水润度不足,表面偏干燥,容易出现干纹。",
|
||||
"改善": "水分分 {water_score};缺水面积 {water_area}%,{water_severity_note}肌肤水润度有待提升,建议加强补水与保湿。",
|
||||
"良好": "水分分 {water_score};缺水面积 {water_area}%、肌肤含水量处于健康水平,整体水润度良好。",
|
||||
"优秀": "水分分 {water_score};角质层含水量充足,肌肤屏障锁水能力强,表面饱满水润,无干燥紧绷表现。"
|
||||
},
|
||||
@@ -56,7 +56,7 @@
|
||||
"wrinkles": {
|
||||
"改善": {
|
||||
"care": "重视纹路管理,日常可使用含有肽类、胶原类成分的淡纹精华,针对眼周、法令纹等动态纹高发区域配合点按手法,遏制静态纹转化,帮肌肤恢复平滑细腻的状态。",
|
||||
"lifestyle": "保证睡眠,注意睡姿,减少面部长期受压;减少夸张表情,避免揉眼、托腮等表情性挤压习惯,减少纹路加深。"
|
||||
"lifestyle": "注意睡姿,减少面部长期受压;减少夸张表情,避免揉眼、托腮等表情性挤压习惯,减少纹路加深。"
|
||||
},
|
||||
"良好": {
|
||||
"care": "加强日常淡纹与肌肤弹润护理,叠加使用含肽类、胶原类成分的淡纹精华,提升肌肤水润度与饱满感,维持肤表平滑。",
|
||||
|
||||
+34
-10
@@ -85,9 +85,30 @@
|
||||
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 viewP = cat.P;
|
||||
if (d[0] === 'color') {
|
||||
viewP = numeric(vars.color_score) ? vars.color_score : vars.tone_scoring && vars.tone_scoring.color_score;
|
||||
valid = vars.melanin != null && numeric(viewP);
|
||||
level = valid ? (viewP < 80 ? '改善' : viewP < 90 ? '良好' : '优秀') : null;
|
||||
}
|
||||
if (d[0] === 'water') {
|
||||
// Water copy/advice is independent of pigment/dark circles. Reuse
|
||||
// the existing water cross-check; never change dimension scoring.
|
||||
var waterScore = vars.water_score;
|
||||
var waterValid = numeric(waterScore) && waterScore >= 0 && waterScore <= 100;
|
||||
viewP = waterValid ? waterScore : null;
|
||||
if (waterValid && numeric(vars.water_sev) && vars.water_sev >= 60 && vars.water_sev <= 100 && waterScore >= 80) viewP = 100 - vars.water_sev;
|
||||
valid = waterValid;
|
||||
level = valid ? (viewP < 80 ? '改善' : viewP < 90 ? '良好' : '优秀') : null;
|
||||
}
|
||||
var template = valid && level ? Copy.conclusion[d[0]][level] : '';
|
||||
if (d[0] === 'water' && valid) {
|
||||
vars.water_severity_note = numeric(vars.water_sev) && vars.water_sev >= 0 && vars.water_sev <= 100
|
||||
? (vars.water_sev >= 60 ? '缺水程度较高(严重度 {water_sev}),' : '缺水严重度 {water_sev},') : '';
|
||||
if (viewP !== vars.water_score) template = '水分分 {water_score};缺水面积 {water_area}%,缺水严重度 {water_sev}。水分分数与缺水指标不一致,本次按缺水指标评估,建议加强补水与保湿。';
|
||||
// Resolve the optional phrase before normal scalar substitution.
|
||||
template = template.replace(/\{water_severity_note\}/g, vars.water_severity_note);
|
||||
}
|
||||
if (d[0] === 'contour') {
|
||||
var severity = vars.dark_circle_sev;
|
||||
var description = numeric(severity) ? ['无明显黑眼圈', '黑眼圈轻度', '黑眼圈中度', '黑眼圈重度'][severity] : null;
|
||||
@@ -135,18 +156,21 @@
|
||||
}
|
||||
var details = d[0] === 'wrinkles' ? wrinkleDetails(result) : null;
|
||||
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,
|
||||
return { key: d[0], name: d[1], dim: d[2], source: d[3], P: viewP, level: level || null,
|
||||
text: valid ? fill(template, vars) : '本次未检出有效数据,请重新拍摄后查看。',
|
||||
details: details, 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 focus = focusOf(vm);
|
||||
function priority(view) { return focus && view.dim === focus.key ? 0 : 1; }
|
||||
function order(a, b) { return a.P - b.P || priority(a) - priority(b) || views.indexOf(a) - views.indexOf(b); }
|
||||
// Select globally weakest three FIRST, then move selected focus members
|
||||
// to the front. Never insert an unselected stronger focus-category view.
|
||||
var chosen = views.filter(function(v) { return v.valid && numeric(v.P) && v.advice; }).sort(order).slice(0,3);
|
||||
chosen.sort(function(a,b) { return priority(a) - priority(b) || order(a,b); });
|
||||
var care = chosen.map(function(v) { return { key: v.key, name: v.name, dim: v.dim, P: v.P, level: v.level,
|
||||
priority: priority(v) === 0, 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 + '+feedback-2026-10-12', dims: dimNames, views: views, care: care, product: product, focus: focusOf(vm) };
|
||||
return { version: Copy.version + '+feedback-2026-10-12+care-2026-10-15', careRule: 'seven-lowest-three-focus-first-v1', dims: dimNames, views: views, care: care, product: product, focus: focus };
|
||||
}
|
||||
return { dimensionScore: dimensionScore, build: build, products: products, levelMap: levelMap, dimNames: dimNames, wrinkleDetails: wrinkleDetails, focusOf: focusOf, customerText: customerText };
|
||||
});
|
||||
|
||||
+10
-2
@@ -752,9 +752,16 @@
|
||||
var d = DIM_DEFS[i], ps = [], j;
|
||||
for (j = 0; j < CAT_DEFS.length; j++) {
|
||||
if (CAT_DEFS[j].dim !== d.key) continue;
|
||||
if (d.key === 'vita' && CAT_DEFS[j].key === 'tone') continue; // retired combined score
|
||||
var P = cats[CAT_DEFS[j].key].P;
|
||||
if (P != null) ps.push(P);
|
||||
}
|
||||
if (d.key === 'vita') {
|
||||
var toneVars = cats.tone.vars;
|
||||
[toneVars.color_score, toneVars.tone_scoring && toneVars.tone_scoring.water_adjusted_score].forEach(function(score) {
|
||||
if (isNum(score)) ps.push(score);
|
||||
});
|
||||
}
|
||||
var dP = ps.length ? Math.min.apply(null, ps) : null;
|
||||
if (!ps.length) notes.push(d.name + ':旗下分类数据全部缺失,维度不参与评分');
|
||||
dims[d.key] = { name: d.name, P: dP, S: sShow(dP), level: levelOf(dP) };
|
||||
@@ -848,6 +855,7 @@
|
||||
return {
|
||||
total: weightedTotal(dims),
|
||||
totalRule: 'dimensions-433-v1',
|
||||
vitaScoreRule: 'independent-color-water-smooth-min-v1',
|
||||
wrinkleScoreRule: 'api-overall-v1',
|
||||
acneScoreRule: 'three-view-type-max-v1',
|
||||
skinAgeRaw: skinAge,
|
||||
@@ -984,7 +992,7 @@ if (typeof require === 'function' && typeof module !== 'undefined' && require.ma
|
||||
ok(vm.cats.sens.P === 98, '敏感P = min(98, 100−0.1×1.5=99.85) = 98(面积 0.001 小数口径×100)');
|
||||
ok(vm.cats.acne.P === 85, '痘痘P = min(分级映射85, 100−14.5=85.5) = 85');
|
||||
ok(vm.cats.wrinkles.S === 7.69 && vm.cats.smooth.S === 9.45 && vm.cats.tone.S === 9.45, 'S=7+3×P/100 两位小数(含 9.445→9.45 浮点修正)');
|
||||
ok(vm.dims.firm.P === 23 && vm.dims.vita.P === 81.5 && vm.dims.stab.P === 85, '维度木桶 min:紧塑力23 / 活力感81.5 / 稳定力85');
|
||||
ok(vm.dims.firm.P === 23 && vm.dims.vita.P === 80 && vm.dims.stab.P === 85, '维度木桶 min:紧塑力23 / 独立肤色短板80 / 稳定力85');
|
||||
ok(vm.skinAgeRaw === 20 && vm.skinAgeDisplay === 20 && vm.ageClampNote === '', '肌肤年龄直接展示原值20,不按实际年龄钳制');
|
||||
ok(vm.group === '25+组', '原始肌龄20 → 25+组');
|
||||
ok(vm.essence.name === '25+束紧精华' && vm.recommendation.tier === 1,
|
||||
@@ -1015,7 +1023,7 @@ if (typeof require === 'function' && typeof module !== 'undefined' && require.ma
|
||||
console.log('== T2 木桶 min(显式构造) ==');
|
||||
var vm2 = SS.buildViewModel(clone(SS.MOCK_RESULT), SS.MOCK_SIDE, { realAge: 40 });
|
||||
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.vita.P === Math.min(vm2.cats.smooth.P, vm2.cats.tone.vars.color_score, vm2.cats.tone.vars.tone_scoring.water_adjusted_score)
|
||||
&& vm2.dims.stab.P === Math.min(vm2.cats.sens.P, vm2.cats.acne.P), '三维度 P = min(旗下两分类)');
|
||||
ok(vm2.group === '25+组', '实际年龄40不影响推荐,原始肌龄20仍为25+组');
|
||||
|
||||
|
||||
@@ -281,6 +281,11 @@ function fillSuccess(rec, fpJson, persist = true) {
|
||||
rec.skin_age_display = vm.skinAgeDisplay;
|
||||
rec.recommendation = vm.recommendation;
|
||||
rec.presentation = ReportUI.build(vm, fpJson.result);
|
||||
rec.vita_score_rule = vm.vitaScoreRule;
|
||||
rec.sub_scores = Object.fromEntries(rec.presentation.views.map(view => [view.key, {
|
||||
P: view.P, S: view.P == null ? null : Math.round((Math.max(7, Math.min(10, 7 + 3 * view.P / 100)) + 1e-9) * 100) / 100,
|
||||
level: view.level === '改善' ? '预警' : view.level === '良好' ? '改善' : view.level === '优秀' ? '良好' : null
|
||||
}]));
|
||||
rec.total_score = vm.total;
|
||||
rec.total_score_rule = vm.totalRule;
|
||||
rec.wrinkle_score_rule = vm.wrinkleScoreRule;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
const assert=require('node:assert/strict'),SS=require('../js/skin-score'),UI=require('../js/report-ui'),Copy=require('../js/report-copy');
|
||||
const keys=['contour','wrinkles','color','smooth','water','sens','acne'];
|
||||
function sample(scores,focus='firm'){
|
||||
const vm=SS.buildViewModel(structuredClone(SS.MOCK_RESULT),SS.MOCK_SIDE,{});
|
||||
for(const k of ['contour','wrinkles','smooth','sens','acne']){vm.cats[k].P=scores[k];vm.cats[k].level=scores[k]==null?null:scores[k]<80?'预警':scores[k]<90?'改善':'良好';}
|
||||
Object.assign(vm.cats.tone.vars,{melanin:scores.color,color_score:scores.color,water_score:scores.water,water_sev:0});
|
||||
vm.cats.tone.vars.tone_scoring.color_score=scores.color;
|
||||
vm.cats.acne.vars.acne_counts={closed_comedones:0,acne:0,acne_pustule:0,acne_nodule:0,acne_mark:0};
|
||||
vm.cats.acne.vars.acne_cnt=0;
|
||||
for(const dim of ['firm','vita','stab'])vm.dims[dim].P=focus==null?null:dim===focus?10:99;
|
||||
const before=JSON.stringify(vm),ui=UI.build(vm,SS.MOCK_RESULT);assert.equal(JSON.stringify(vm),before);
|
||||
return{vm,ui};
|
||||
}
|
||||
function check(values,focus,expected){const scores=Object.fromEntries(keys.map((k,i)=>[k,values[i]])),x=sample(scores,focus);assert.deepEqual(x.ui.care.map(v=>v.key),expected);assert(x.ui.care.length<=3);for(const c of x.ui.care){assert.equal(c.text,Copy.care[c.key][c.level].care+Copy.care[c.key][c.level].lifestyle);assert.equal(c.priority,c.dim===focus);}return x;}
|
||||
check([20,10,30,90,95,92,99],'firm',['wrinkles','contour','color']);
|
||||
check([30,95,10,90,20,99,98],'firm',['contour','color','water']);
|
||||
check([90,30,10,20,95,96,99],'firm',['wrinkles','color','smooth']);
|
||||
check([99,98,40,30,20,97,96],'vita',['water','smooth','color']);
|
||||
check([95,96,10,20,30,90,99],'firm',['color','smooth','water']);
|
||||
check([80,80,80,80,80,80,80],'stab',['sens','acne','contour']);
|
||||
check([80,80,80,80,80,80,80],null,['contour','wrinkles','color']);
|
||||
check([79.999,79.998,79.997,99,99,99,99],'firm',['wrinkles','contour','color']);
|
||||
check([null,null,50,null,60,null,null],'firm',['color','water']);
|
||||
check([null,null,null,null,null,null,null],null,[]);
|
||||
const x=check([99,98,79.99,99,90,99,99],'vita',['color','water','wrinkles']);
|
||||
assert.equal(x.ui.views.find(v=>v.key==='color').level,'改善');assert.equal(x.ui.views.find(v=>v.key==='water').level,'优秀');
|
||||
assert.equal(x.ui.careRule,'seven-lowest-three-focus-first-v1');
|
||||
const heavy=sample(Object.fromEntries(keys.map(k=>[k,95])),'stab');heavy.vm.cats.acne.vars.acne_counts.acne_nodule=1;heavy.vm.cats.acne.vars.acne_cnt=1;
|
||||
assert.equal(UI.build(heavy.vm,{}).views.find(v=>v.key==='acne').level,'改善');
|
||||
assert(!Copy.care.wrinkles['改善'].lifestyle.startsWith('保证睡眠'));
|
||||
console.log('PASS care: global lowest3, focus-first selected only, two/one/no focus members, tie/document order, raw precision, missing, independent color/water, acne guard, exact copy and immutable scores');
|
||||
@@ -19,6 +19,7 @@ for(const [P,level] of [[79.99,'改善'],[80,'良好'],[89.99,'良好'],[90,'优
|
||||
else result.dark_circle_severity={value:severity};
|
||||
const vm=SS.buildViewModel(result,SS.MOCK_SIDE,{});
|
||||
vm.cats.tone.P=P;vm.cats.tone.level=P<80?'预警':P<90?'改善':'良好';
|
||||
vm.cats.tone.vars.color_score=P; // Test independent color thresholds.
|
||||
const before=JSON.stringify({vm,result});
|
||||
const presentation=UI.build(vm,result),view=presentation.views.find(v=>v.key==='color');
|
||||
const valid=Number.isInteger(severity)&&severity>=0&&severity<=3;
|
||||
|
||||
@@ -114,6 +114,8 @@ function main() {
|
||||
tr.cats.acne = { P: 99, S: 9.97, tier: '良好档', copy: '检出1处皮损(闭口粉刺1处)。建议维持清洁与控油节奏,注意作息与饮食。' };
|
||||
tr.avgS = 9.53;
|
||||
tr.summary = tr.summary.replace('六分类S均分9.54', '六分类S均分9.53');
|
||||
// Authorized independent minimum: water90 no longer averaged up to91.5.
|
||||
tr.dims.vita.P = 90; tr.dims.vita.S = 9.7;
|
||||
}
|
||||
var vm = SkinScore.buildViewModel(fixture.result, fixture.side, tr.profile);
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ try{
|
||||
assert(Math.abs(geo.heading.w-595/1080*width)<.1,'Figma text group width scales with preview');
|
||||
const stabilityFont=await p.locator('.dimension-stability-title').evaluate(e=>parseFloat(getComputedStyle(e).fontSize));
|
||||
assert(Math.abs(geo.headingFont-stabilityFont)<.01,'bottom title matches stability heading font size at every width');
|
||||
const productFonts=await p.evaluate(()=>['#product-title','#product-name'].map(s=>parseFloat(getComputedStyle(document.querySelector(s)).fontSize)));
|
||||
assert(Math.abs(productFonts[0]-14.467593)<.01,'restore original product title size, including small screens');
|
||||
assert(Math.abs(productFonts[1]-12.013166)<.01,'gray subtitle enlarged proportionally');
|
||||
assert(Math.abs((geo.heading.x+geo.heading.w/2)-(geo.care.x+geo.care.w/2)-width/1080)<.1,'whole title group centered, retaining 1px design offset');
|
||||
assert(geo.product.bottom<=geo.care.bottom);assert(geo.disclaimer.y>=geo.care.bottom);
|
||||
assert(geo.title.right<=geo.info.right+1&&geo.name.right<=geo.info.right+1,'text must not overlap image');
|
||||
|
||||
@@ -70,6 +70,9 @@ try {
|
||||
assert.equal(adminRecord.total_score_rule, 'dimensions-433-v1');
|
||||
assert.deepEqual(adminRecord.acne_scoring,result.vm.cats.acne.vars.acne_scoring);
|
||||
assert.deepEqual(adminRecord.tone_scoring,result.vm.cats.tone.vars.tone_scoring);
|
||||
assert.equal(adminRecord.vita_score_rule,'independent-color-water-smooth-min-v1');
|
||||
assert.equal(Object.keys(adminRecord.sub_scores).length,7);
|
||||
assert.equal(adminRecord.dims.vita.P,Math.min(...['color','water','smooth'].map(k=>adminRecord.sub_scores[k].P).filter(v=>v!=null)));
|
||||
if(process.env.H5_ACNE_MAX_TEST==='1') {
|
||||
assert.deepEqual(result.vm.cats.acne.vars.acne_counts,{closed_comedones:5,acne:1,acne_pustule:0,acne_nodule:0,acne_mark:4});
|
||||
assert.equal(adminRecord.acne_scoring.deduction,13);assert.equal(adminRecord.cats.acne.P,87);
|
||||
|
||||
@@ -10,7 +10,7 @@ function run(dc,options={}){
|
||||
return{vm,r,v:vm.cats.tone.vars};
|
||||
}
|
||||
const a=run(50);near(a.v.color_score,75*.8+50*.2);near(a.vm.cats.tone.P,75);
|
||||
assert.equal(a.vm.cats.tone.S,9.25);assert.equal(a.vm.dims.vita.S,9.25);
|
||||
assert.equal(a.vm.cats.tone.S,9.25);assert.equal(a.vm.dims.vita.S,9.1);
|
||||
assert(!UI.build(a.vm,a.r).views.find(v=>v.key==='color').text.includes('占肤色项20%'));
|
||||
for(const dc of [0,100]){const x=run(dc);near(x.v.color_score,75*.8+dc*.2);near(x.vm.cats.tone.P,(x.v.color_score+80)/2);}
|
||||
for(const dc of [null,undefined,-1,101,NaN,Infinity]){const x=run(dc);assert.equal(x.v.dark_circle_score,null);near(x.v.color_score,75);near(x.vm.cats.tone.P,77.5);}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
const assert=require('node:assert/strict'),S=require('../js/skin-score');
|
||||
function run(melanin,water,dark){const r=structuredClone(S.MOCK_RESULT);Object.assign(r.score_info,{melanin_score:melanin,water_score:water,dark_circle_score:dark});r.melasma={value:0};r.freckle={value:0};r.water={water_severity:3};return S.buildViewModel(r,S.MOCK_SIDE,{});}
|
||||
for(const [m,w,d]of[[66,97,30],[99,20,99],[99,99,99],[null,97,null],[null,null,null]]){
|
||||
const v=run(m,w,d),vars=v.cats.tone.vars,values=[v.cats.smooth.P,vars.color_score,vars.tone_scoring&&vars.tone_scoring.water_adjusted_score].filter(x=>typeof x==='number'&&Number.isFinite(x));
|
||||
assert.equal(v.dims.vita.P,Math.min(...values));assert.equal(v.vitaScoreRule,'independent-color-water-smooth-min-v1');assert.equal(v.total,S.weightedTotal(v.dims));
|
||||
}
|
||||
assert(Math.abs(run(66,97,30).dims.vita.P-58.8)<1e-9);
|
||||
console.log('PASS independent vita min: color/water/smooth bottleneck, missing inputs, version and weighted total');
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
const assert=require('node:assert/strict'),SS=require('../js/skin-score'),UI=require('../js/report-ui'),Copy=require('../js/report-copy');
|
||||
function run(score,severity=3,pigment=66,dc=30){
|
||||
const r=structuredClone(SS.MOCK_RESULT);Object.assign(r.score_info,{water_score:score,melanin_score:pigment,dark_circle_score:dc});
|
||||
r.melasma={value:0};r.freckle={value:0};r.water={water_severity:severity,water_area:.03};
|
||||
const vm=SS.buildViewModel(r,SS.MOCK_SIDE,{}),before=JSON.stringify({r,vm});
|
||||
const presentation=UI.build(vm,r);assert.equal(JSON.stringify({r,vm}),before);
|
||||
return{r,vm,presentation,water:presentation.views.find(v=>v.key==='water')};
|
||||
}
|
||||
const example=run(97);assert.equal(example.vm.cats.tone.P,77.9);assert.equal(example.water.P,97);assert.equal(example.water.level,'优秀');
|
||||
assert(!/含水量偏低|缺水比较严重|水润度不足/.test(example.water.text));assert(example.water.text.includes('97'));
|
||||
assert.deepEqual(example.water.advice,Copy.care.water['优秀']);
|
||||
assert(!example.presentation.care.some(v=>v.name==='水分'),'healthy water97 should not displace a weaker item in global bottom three');
|
||||
for(const[p,level]of[[0,'改善'],[79.99,'改善'],[80,'良好'],[89.99,'良好'],[90,'优秀'],[100,'优秀']]){
|
||||
for(const pigment of[0,50,100]){const x=run(p,3,pigment,0);assert.equal(x.water.level,level);assert.equal(x.water.P,p);assert.deepEqual(x.water.advice,Copy.care.water[level]);}
|
||||
}
|
||||
const crossed=run(97,70);assert.equal(crossed.water.P,30);assert.equal(crossed.water.level,'改善');assert(crossed.water.text.includes('分数与缺水指标不一致'));assert.equal(crossed.vm.cats.tone.vars.tone_scoring.water_adjusted_score,30);
|
||||
assert(run(50,70).water.text.includes('缺水程度较高'));
|
||||
assert(!run(50,3).water.text.includes('程度较高'));
|
||||
assert(!run(50,null).water.text.includes('严重度'));
|
||||
for(const score of[null,undefined,-1,101,NaN,Infinity]){const x=run(score);assert.equal(x.water.valid,false);assert.equal(x.water.advice,null);assert(!x.presentation.care.some(v=>v.name==='水分'));}
|
||||
console.log('PASS water: 97 vs combined77.9, independent water copy/advice, 80/90 boundaries, true severity, existing cross-check, missing/invalid, scoring immutable');
|
||||
@@ -50,12 +50,14 @@
|
||||
|
||||
#### 5\.5 水分(透亮感)
|
||||
|
||||
**【改善】**水分分 \{water\_score\};缺水面积 \{water\_area\}%、肌肤缺水比较严重 \{water\_sev\},肌肤含水量偏低,水润度不足,表面偏干燥,容易出现干纹。
|
||||
**【改善】**水分分 \{water\_score\};缺水面积 \{water\_area\}%,\{water\_severity\_note\}肌肤水润度有待提升,建议加强补水与保湿。
|
||||
|
||||
**【良好】**水分分 \{water\_score\};缺水面积 \{water\_area\}%、肌肤含水量处于健康水平,整体水润度良好。
|
||||
|
||||
**【优秀】** 水分分 \{water\_score\};角质层含水量充足,肌肤屏障锁水能力强,表面饱满水润,无干燥紧绷表现。
|
||||
|
||||
水分分档补充(2026-10-15):文案及水分护理建议独立使用水分项分档,低于80为改善、80至低于90为良好、90及以上为优秀,不再跟随肤色水润合成分。沿用现有水分交叉校验:水分分≥80且缺水严重度≥60时,水分项按100减严重度评估,并在文案中明确提示分数与缺水指标不一致。\{water\_severity\_note\}仅在严重度为0~100的有效数值时展示:≥60描述缺水程度较高,其他值仅报告严重度数值;缺失时省略。维度评分、综合评分、推荐及护理类别选取不变。
|
||||
|
||||
#### 5\.6 泛红(稳韧力)
|
||||
|
||||
**【改善】** 泛红面积达 \{sens\_area\}%,肌肤泛红明显,敏感区域可见泛红;对外界刺激耐受度不足,容易受外界因素影响产生状态波动。
|
||||
@@ -80,6 +82,8 @@
|
||||
|
||||
### 护理建议(全量文本,按需求摘抄)
|
||||
|
||||
选择规则(2026-10-15):从轮廓、皱纹、肤色、平滑度、水分、泛红、痘痘七项有效独立分数中选最低的三项;肤色、水分不再共用合成分。分数相同优先选上方“优先关注”大维度中的小项,再按本节七项顺序。选完三项后,将属于优先关注大维度的入选项前置,各组内仍按低分优先排列,不强行补入未入选项。有效项不足三项按实际数量展示。各项按自己的分数取改善/良好/优秀护理及生活方式全文,痘痘保留已有皮损严重度文案约束。三维度、综合得分及产品推荐不变。肤色分析文案同步按独立肤色项分档,黑眼圈程度描述仍独立读取实际检测等级。
|
||||
|
||||
#### 6\.1 轮廓
|
||||
|
||||
【改善·护理】重点进行轮廓紧致管理,关注面中、苹果肌与下颌线区域。日常增加紧致精华步骤,配合由下向上的轻柔提升按摩,帮助肌肤维持弹润和支撑感,让轮廓看起来更紧实。
|
||||
@@ -104,7 +108,7 @@
|
||||
|
||||
【改善·护理】重视纹路管理,日常可使用含有肽类、胶原类成分的淡纹精华,针对眼周、法令纹等动态纹高发区域配合点按手法,遏制静态纹转化,帮肌肤恢复平滑细腻的状态。
|
||||
|
||||
【改善·生活方式】保证睡眠,注意睡姿,减少面部长期受压;减少夸张表情,避免揉眼、托腮等表情性挤压习惯,减少纹路加深。
|
||||
【改善·生活方式】注意睡姿,减少面部长期受压;减少夸张表情,避免揉眼、托腮等表情性挤压习惯,减少纹路加深。
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user