feat(h5): align report care and single-product section with updated design
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# 报告底部 Figma 还原
|
||||
|
||||
设计文件 53PGFOThvhZwf2TPUHAcUz,稳韧力组1:47、底部组1:65。仅本地修改,尚未提交或部署。
|
||||
|
||||
- 大标题前移到日常护理上方、左对齐;日常护理及推荐产品合为一个自适应白卡。
|
||||
- 标题1:369为两行文字组;按用户最新确认,两行文字各自居中,整体按白卡居中并保留1设计像素偏移。文字组随屏幕缩放,字号与上方稳韧力统一为22.106597px、行距28.738542px,不再随宽屏放大文字。
|
||||
- 护理建议改为日常护理,删除固定结束语,保留按检测结果生成的护理内容。
|
||||
- 白卡内增加推荐产品小标题。仍仅显示算法选中的一款,不生成产品列表或切换入口。
|
||||
- 三款副标题分别为焕活光泽 透亮紧致、恢复弹性 紧实利落、强韧屏障 轮廓向上,不再显示双仓精华液第二行。
|
||||
- 免责声明移到白卡下方,补充仅根据您最近的测肤记录推荐。
|
||||
- 稳韧力标题、页签及段落字体/行距按设计尺寸微调;动态检测图、文案、评分和跟手滑动不变。
|
||||
- 历史报告依旧使用当时推荐档位与护理文本,仅按该档位更新产品展示文案和素材;不改写保存数据。
|
||||
|
||||
## 静态素材核对
|
||||
|
||||
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屏幕略缩产品文字避免遮挡。
|
||||
|
||||
## 验证
|
||||
|
||||
report-bottom-figma.mjs 覆盖三款选中产品、320/375/414/480宽度、元素顺序、白卡嵌套、图片/徽标比例、文字不遮挡图片、历史推荐对象不变、缺少肌龄与长护理内容。另运行报告持久化、游客隐私、产品推荐及报告滑动/布局回归。三款375px截图位于私有临时测试目录,不纳入Git。
|
||||
@@ -4,7 +4,7 @@
|
||||
"2": "app.js",
|
||||
"3": "skin-score.js",
|
||||
"4": "customer-feedback-second.js",
|
||||
"5": "extractFaces",
|
||||
"5": "extractFaceTensors",
|
||||
"6": "countdown-capture-browser.mjs",
|
||||
"7": "test/profile-store.js",
|
||||
"8": "admin.js",
|
||||
@@ -16,7 +16,7 @@
|
||||
"14": "showScreen",
|
||||
"15": "TinyYolov2",
|
||||
"16": "巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范",
|
||||
"17": "getEnv",
|
||||
"17": "extractFaces",
|
||||
"18": "1'me肌肤状态检测 H5",
|
||||
"19": "customer-feedback-fourth.js",
|
||||
"20": "build_fixtures.py",
|
||||
@@ -25,7 +25,7 @@
|
||||
"23": "facepp-skinanalyze(旷视皮肤分析专业版调用技能)",
|
||||
"24": "巨子测肤 · 1'me 语音播报内容设计文档 V1.0",
|
||||
"25": "mobile-select.iife.min.js",
|
||||
"26": ".extractWeights",
|
||||
"26": "NeuralNetwork",
|
||||
"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": "TinyYolov2Base",
|
||||
"38": "customer-feedback-fourth.mjs",
|
||||
"39": "UI交互界面调整",
|
||||
"40": "第四轮反馈修改与验收",
|
||||
"41": "js/beijing-time.js",
|
||||
"42": "layer_at",
|
||||
"43": ".run",
|
||||
"43": "extractAllFacesAndComputeResults",
|
||||
"44": "start-local.sh",
|
||||
"45": "vizCompose",
|
||||
"45": "head-pose.js",
|
||||
"46": ".forwardInput",
|
||||
"47": "e",
|
||||
"47": ".toString",
|
||||
"48": "已修改",
|
||||
"49": "mobile-select/README.md",
|
||||
"50": "call_skinanalyze_3view.sh",
|
||||
@@ -76,7 +76,7 @@
|
||||
"74": "report-copy.js",
|
||||
"75": "prepare_h5_assets.py",
|
||||
"76": "报告页滑动防冲突-2026-10-13.md",
|
||||
"77": "drawFaceExpressions",
|
||||
"77": "vizCompose",
|
||||
"78": "height",
|
||||
"79": "登录反馈与加载优化(2026-10-12)",
|
||||
"80": "线上微信登录部署记录",
|
||||
@@ -92,16 +92,16 @@
|
||||
"90": "customer-feedback.mjs",
|
||||
"91": "wi",
|
||||
"92": "客户反馈修改(2026-10-12)",
|
||||
"93": "k",
|
||||
"93": "capture-diagnostics.js",
|
||||
"94": "第三轮反馈:PSD 对齐、验收及上线记录",
|
||||
"95": "NeuralNetwork",
|
||||
"95": "recommendation.js",
|
||||
"96": "i",
|
||||
"97": "account-client.js",
|
||||
"98": ".runAndExtendWithFaceDetections",
|
||||
"98": "drawFaceExpressions",
|
||||
"99": "normalize",
|
||||
"100": ".runAndExtendWithFaceDetection",
|
||||
"101": "wechat-fixture.cjs",
|
||||
"102": "wechat-browser.mjs",
|
||||
"102": "report-persistence.mjs",
|
||||
"103": "第四轮反馈/傅艳NEW与项思炼的会话 2026年10月12日.md",
|
||||
"104": "export_fourth_feedback_assets.py",
|
||||
"105": "capture-quality-browser.mjs",
|
||||
@@ -115,11 +115,11 @@
|
||||
"113": "swipe-track.js",
|
||||
"114": "optimize_delivery_images.py",
|
||||
"115": "痘痘按三视图各类型最大数量计分",
|
||||
"116": "extractAllFacesAndComputeResults",
|
||||
"117": "initialize",
|
||||
"116": "age",
|
||||
"117": ".runAndExtendWithFaceDetections",
|
||||
"118": "f",
|
||||
"119": "肤色文案与实际黑眼圈等级-2026-10-14.md",
|
||||
"120": "disposeUnusedWeightTensors",
|
||||
"120": "AgeGenderNet",
|
||||
"121": ".draw",
|
||||
"122": "doCapture",
|
||||
"123": "评分圈内居中、基础信息页固定与正脸语音修复",
|
||||
@@ -128,15 +128,17 @@
|
||||
"126": "wrinkle-case-browser.mjs",
|
||||
"127": "splash-brand-browser.mjs",
|
||||
"128": "后台北京时间统一",
|
||||
"129": "FaceDetection",
|
||||
"129": "报告底部 Figma 还原",
|
||||
"130": "wrinkle-overall.js",
|
||||
"131": "原始肌龄显示与鸿蒙滚轮兼容",
|
||||
"132": "harmony-picker.mjs",
|
||||
"133": "FaceLandmarks68",
|
||||
"134": "camera-flip-browser.mjs",
|
||||
"135": "恢复321与色斑案例复测",
|
||||
"136": "js/profile-store.js",
|
||||
"137": "皱纹改用接口整体评分",
|
||||
"138": "DetectSingleFaceLandmarksTask",
|
||||
"139": ".mul",
|
||||
"142": "tone-dark-circle.js",
|
||||
"144": "肤色项加入黑眼圈20%,色素图30%叠加",
|
||||
"145": "PredictAllAgeAndGenderWithFaceAlignmentTask",
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"0": "c9388b28d21814cc", "1": "cb6ea50bd4e4a5ca", "2": "fb3668625bb1d5ad", "3": "5bfb236350c342ee", "4": "4b1835ae3a82cf12", "5": "4d988c274608a140", "6": "4b54405c5a282677", "7": "4ac0e88610049064", "8": "3d958eb3ed2a04df", "9": "5b3557ee5c2bf900", "10": "7e842e2bd8e95fd4", "11": "e2a8a6f58d7efe84", "12": "cba798df74f6df27", "13": "7e3b558a587a4ebe", "14": "58417b287cc79e90", "15": "c96276581a8c98d4", "16": "95add6a975c0cb72", "17": "6ee33da61a3bade4", "18": "f93d5d85e671fcee", "19": "5272556cf61d08b3", "20": "aecf2fce44ba49c5", "21": "f4675fc43b3461fa", "22": "44afcd0daafd8e6d", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "46e8db3e6e3f37ea", "26": "3047344baec2ef10", "27": "eab427ce9a5219e9", "28": "b07445f7442a552e", "29": "c608f1c6492e1cb1", "30": "73c13793fca09f56", "31": "fbbcfc059751cc6a", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "241be5abeab1da6f", "36": "a7d375041779bad4", "37": "cb8f26249485324a", "38": "34115c5ef9f07f6f", "39": "fdd95375b4a5ddb3", "40": "5e546676ab96de03", "41": "a7a205c1adc39fe5", "42": "916170b9f5d7346b", "43": "6cda159cdef28f96", "44": "852c1bb2446edd9c", "45": "288c2a98831b0021", "46": "880a74c6d255e5cc", "47": "b35c31ebe34b7c11", "48": "cf2f2424bc00436f", "49": "1f976711cda158dc", "50": "bbb2b57d72922b16", "51": "eb6a182204867275", "52": "2ec3c8c088568ba9", "53": "68c45056378341a7", "54": "c58d41e8e580fdc6", "55": "812950f51be20e40", "56": "c92bed61fc5b4cff", "57": "f2a40b5f1b29f669", "58": "f587d45cb0817ca2", "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": "a0bc88eb14b70170", "78": "746b316833e9c203", "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": "664f8b17c5d7a9aa", "92": "fced244d93677d90", "93": "f714f54050b7c767", "94": "713d04996c4627df", "95": "d96493a5f110bd4c", "96": "1c573600c092f3fd", "97": "505ea719b994ac5e", "98": "f45aa61f1a2036bf", "99": "516c54d9b6b5dd42", "100": "5a9014c4a7f87699", "101": "beb276de6301634c", "102": "2b037735e1f5b0f6", "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": "ec2ef7fbebe8cd34", "117": "eb3733e409dc7411", "118": "3a183d8ae5649214", "119": "7485900c7157ebbd", "120": "5d94cf57d5d1a6fb", "121": "bf75bfc99d4f9e34", "122": "4f6d51a884cc3f06", "123": "b091e3eb82b456eb", "124": "df789af52163282e", "125": "e4f29216745ec758", "126": "d32da0afe8e66daa", "127": "006218e34885dbe0", "128": "1c2b248bd950f405", "129": "287d60115d9acda8", "130": "d724edff31ad0cb8", "131": "482dbb7ec33d8c23", "132": "3daacabc5062b554", "133": "89b7dc6810db2c6a", "134": "e7c90d6ef8276a1e", "135": "977cfc41f0c4b0b1", "137": "2e16ad304d257483", "138": "23f1d406f6c779ae", "142": "d1f85bf935ee51b4", "144": "cb06127f3461dec5", "145": "92ab3e5134ed8685", "146": "9a25b1230b5fe649", "147": "0e6cad06ebfcfb29", "148": "65718282b3c32109", "149": "01f68dfc34a29d32", "150": "8c471c7baeaaca54", "153": "23e1e56f6367f19e"}
|
||||
{"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"}
|
||||
+107
-97
@@ -1,16 +1,16 @@
|
||||
# Graph Report - juzi (2026-10-15)
|
||||
|
||||
## Corpus Check
|
||||
- 138 files · ~4,914,067 words
|
||||
- 140 files · ~4,961,406 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 1626 nodes · 3102 edges · 147 communities (117 shown, 30 thin omitted)
|
||||
- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 214 edges (avg confidence: 0.57)
|
||||
- 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)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `d8c67762`
|
||||
- Built from commit: `60ae6c97`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
- app.js
|
||||
- skin-score.js
|
||||
- customer-feedback-second.js
|
||||
- extractFaces
|
||||
- extractFaceTensors
|
||||
- test/profile-store.js
|
||||
- admin.js
|
||||
- __awaiter
|
||||
@@ -31,7 +31,7 @@
|
||||
- showScreen
|
||||
- TinyYolov2
|
||||
- 巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范
|
||||
- getEnv
|
||||
- extractFaces
|
||||
- 1'me肌肤状态检测 H5
|
||||
- customer-feedback-fourth.js
|
||||
- build_fixtures.py
|
||||
@@ -40,7 +40,7 @@
|
||||
- facepp-skinanalyze(旷视皮肤分析专业版调用技能)
|
||||
- 巨子测肤 · 1'me 语音播报内容设计文档 V1.0
|
||||
- mobile-select.iife.min.js
|
||||
- .extractWeights
|
||||
- NeuralNetwork
|
||||
- gen_voice.py
|
||||
- C
|
||||
- face-api.js 本地化依赖(h5/vendor/faceapi/)
|
||||
@@ -50,16 +50,16 @@
|
||||
- build-fixture.py
|
||||
- customer-feedback.js
|
||||
- UI 外发版 10.09 图片资源
|
||||
- TinyYolov2Base
|
||||
- customer-feedback-fourth.mjs
|
||||
- UI交互界面调整
|
||||
- 第四轮反馈修改与验收
|
||||
- js/beijing-time.js
|
||||
- layer_at
|
||||
- .run
|
||||
- extractAllFacesAndComputeResults
|
||||
- start-local.sh
|
||||
- vizCompose
|
||||
- head-pose.js
|
||||
- .forwardInput
|
||||
- e
|
||||
- .toString
|
||||
- 已修改
|
||||
- mobile-select/README.md
|
||||
- call_skinanalyze_3view.sh
|
||||
@@ -83,7 +83,7 @@
|
||||
- 报告顶部评分与年龄排版
|
||||
- build_report_copy.py
|
||||
- 报告页滑动防冲突-2026-10-13.md
|
||||
- drawFaceExpressions
|
||||
- vizCompose
|
||||
- height
|
||||
- 登录反馈与加载优化(2026-10-12)
|
||||
- 线上微信登录部署记录
|
||||
@@ -98,16 +98,16 @@
|
||||
- 傅艳NEW与项思炼的会话 2026年10月12日.md
|
||||
- wi
|
||||
- 客户反馈修改(2026-10-12)
|
||||
- k
|
||||
- capture-diagnostics.js
|
||||
- 第三轮反馈:PSD 对齐、验收及上线记录
|
||||
- NeuralNetwork
|
||||
- recommendation.js
|
||||
- i
|
||||
- account-client.js
|
||||
- .runAndExtendWithFaceDetections
|
||||
- drawFaceExpressions
|
||||
- normalize
|
||||
- .runAndExtendWithFaceDetection
|
||||
- wechat-fixture.cjs
|
||||
- wechat-browser.mjs
|
||||
- report-persistence.mjs
|
||||
- 第四轮反馈/傅艳NEW与项思炼的会话 2026年10月12日.md
|
||||
- 第三轮反馈20261012/傅艳NEW与项思炼的会话 2026年10月12日.md
|
||||
- 基础信息记忆与肤质拖动
|
||||
@@ -117,11 +117,11 @@
|
||||
- color-copy.js
|
||||
- 微信退出登录-2026-10-13.md
|
||||
- 痘痘按三视图各类型最大数量计分
|
||||
- extractAllFacesAndComputeResults
|
||||
- initialize
|
||||
- age
|
||||
- .runAndExtendWithFaceDetections
|
||||
- f
|
||||
- 肤色文案与实际黑眼圈等级-2026-10-14.md
|
||||
- disposeUnusedWeightTensors
|
||||
- AgeGenderNet
|
||||
- .draw
|
||||
- doCapture
|
||||
- 评分圈内居中、基础信息页固定与正脸语音修复
|
||||
@@ -129,14 +129,16 @@
|
||||
- 报告等待页实拍背景-2026-10-12.md
|
||||
- wrinkle-case-browser.mjs
|
||||
- 后台北京时间统一
|
||||
- FaceDetection
|
||||
- 报告底部 Figma 还原
|
||||
- wrinkle-overall.js
|
||||
- 原始肌龄显示与鸿蒙滚轮兼容
|
||||
- harmony-picker.mjs
|
||||
- FaceLandmarks68
|
||||
- 恢复321与色斑案例复测
|
||||
- js/profile-store.js
|
||||
- 皱纹改用接口整体评分
|
||||
- DetectSingleFaceLandmarksTask
|
||||
- .mul
|
||||
- tone-dark-circle.js
|
||||
- 肤色项加入黑眼圈20%,色素图30%叠加
|
||||
- PredictAllAgeAndGenderWithFaceAlignmentTask
|
||||
@@ -173,11 +175,11 @@
|
||||
## Import Cycles
|
||||
- None detected.
|
||||
|
||||
## Communities (147 total, 30 thin omitted)
|
||||
## Communities (149 total, 30 thin omitted)
|
||||
|
||||
### Community 0 - "face-api.js"
|
||||
Cohesion: 0.02
|
||||
Nodes (36): cn(), computeReshapedDimensions(), Dimensions(), dr(), en(), extractBoundingBoxes(), ff(), ge() (+28 more)
|
||||
Nodes (37): bgrToRgbTensor(), cn(), computeReshapedDimensions(), createBrowserEnv(), createFileSystem(), createNodejsEnv(), Dimensions(), dr() (+29 more)
|
||||
|
||||
### Community 1 - "线上闭环测试(不含真实微信授权)"
|
||||
Cohesion: 0.25
|
||||
@@ -195,25 +197,25 @@ Nodes (59): acneGrade(), buildViewModel(), calcAcne(), calcContour(), calcSens()
|
||||
Cohesion: 0.14
|
||||
Nodes (11): assert, context, events, face, fs, geometry, original, path (+3 more)
|
||||
|
||||
### Community 5 - "extractFaces"
|
||||
### Community 5 - "extractFaceTensors"
|
||||
Cohesion: 0.10
|
||||
Nodes (10): bgrToRgbTensor(), Box(), DetectAllFaceLandmarksTask(), extendWithFaceLandmarks(), extractFaces(), extractFaceTensors(), FaceLandmarks(), isTensor3D() (+2 more)
|
||||
Nodes (12): Box(), DetectAllFaceLandmarksTask(), extendWithFaceDetection(), extendWithFaceLandmarks(), extractFaceTensors(), FaceLandmarks(), isTensor3D(), isWithFaceDetection() (+4 more)
|
||||
|
||||
### Community 7 - "test/profile-store.js"
|
||||
Cohesion: 0.05
|
||||
Nodes (27): age(), clean(), create(), key(), assert, data, empty, now (+19 more)
|
||||
Cohesion: 0.14
|
||||
Nodes (13): assert, data, empty, now, other, Profile, quota, regions (+5 more)
|
||||
|
||||
### Community 8 - "admin.js"
|
||||
Cohesion: 0.19
|
||||
Nodes (31): ageText(), api(), bind(), captureQualityHtml(), closeDetail(), collectFilters(), dimsHtml(), doRetry() (+23 more)
|
||||
|
||||
### Community 9 - "__awaiter"
|
||||
Cohesion: 0.13
|
||||
Nodes (12): __awaiter(), ComposableTask(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow(), __generator(), getModelUris() (+4 more)
|
||||
Cohesion: 0.10
|
||||
Nodes (17): __awaiter(), ComposableTask(), FaceRecognitionNet(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow(), __generator() (+9 more)
|
||||
|
||||
### Community 10 - "n"
|
||||
Cohesion: 0.10
|
||||
Nodes (38): ae(), be(), bi(), ce(), de(), Ef(), er(), FaceMatch() (+30 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (38): ae(), be(), bf(), bi(), ce(), de(), e(), Ef() (+30 more)
|
||||
|
||||
### Community 11 - "lib/accounts.js"
|
||||
Cohesion: 0.06
|
||||
@@ -235,17 +237,17 @@ Nodes (10): enterGuest(), loadAppFont(), loginSucceeded(), logoutWechat(), openO
|
||||
Cohesion: 0.15
|
||||
Nodes (12): 1. 基准与尺寸换算, 2. 色彩规范, 3. 字体规范, 4. 组件切图(assets/svg/), 5. 图片素材(assets/images/,共 15 张), 6. 页面清单(design/ 下有整屏 PNG 预览), 7. 目录结构, 8. 还原建议 (+4 more)
|
||||
|
||||
### Community 17 - "getEnv"
|
||||
Cohesion: 0.20
|
||||
Nodes (17): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), extractImagePatches(), getContext2dOrThrow(), getEnv(), getMediaDimensions() (+9 more)
|
||||
### Community 17 - "extractFaces"
|
||||
Cohesion: 0.21
|
||||
Nodes (17): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), extractFaces(), extractImagePatches(), getContext2dOrThrow(), getEnv() (+9 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.06
|
||||
Nodes (38): evaluate(), finite(), assertPoints(), check(), clamp(), dist(), estimate(), makeFrontal() (+30 more)
|
||||
Cohesion: 0.13
|
||||
Nodes (16): assert, brokenLandmarks, check(), Diagnostics, face(), HeadPose, held, ReportUI (+8 more)
|
||||
|
||||
### Community 20 - "build_fixtures.py"
|
||||
Cohesion: 0.40
|
||||
@@ -267,17 +269,17 @@ Nodes (8): 1. 音频格式约定(已定), 2. 播报清单(14 条), 3. 播放策
|
||||
Cohesion: 0.20
|
||||
Nodes (16): _arrayLikeToArray(), _arrayWithHoles(), _arrayWithoutHoles(), _classCallCheck(), _createClass(), _defineProperties(), h(), _iterableToArray() (+8 more)
|
||||
|
||||
### Community 26 - ".extractWeights"
|
||||
Cohesion: 0.08
|
||||
Nodes (27): createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), extractConvParamsFactory(), extractFCParamsFactory() (+19 more)
|
||||
### Community 26 - "NeuralNetwork"
|
||||
Cohesion: 0.06
|
||||
Nodes (28): createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), extractConvParamsFactory(), extractFCParamsFactory() (+20 more)
|
||||
|
||||
### Community 27 - "gen_voice.py"
|
||||
Cohesion: 0.30
|
||||
Nodes (11): ndarray, Path, gen_countdown(), main(), normalize_clip(), 倒计时单独按字生成再拼接,避免「三、二、一」整句被读成播报腔、与提示音气质漂移。 与提示音共用同一 speaker + instruct;句间留约…, 裁掉过长首尾静音,保留 ≤150ms 边沿,避免提示显迟钝。, 响度归一 −16 LUFS + 转 MP3 48k CBR mono 22050Hz。 (+3 more)
|
||||
|
||||
### Community 28 - "C"
|
||||
Cohesion: 0.13
|
||||
Nodes (24): ao(), C(), cd(), co(), Do(), eo(), fo(), Ft() (+16 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (33): ao(), Bo(), C(), cd(), cl(), co(), Do(), eo() (+25 more)
|
||||
|
||||
### Community 29 - "face-api.js 本地化依赖(h5/vendor/faceapi/)"
|
||||
Cohesion: 0.29
|
||||
@@ -299,9 +301,9 @@ Nodes (27): alternate, approved, assert, crop, details, excellent, fs, model (+1
|
||||
Cohesion: 0.40
|
||||
Nodes (4): UI 外发版 10.09 图片资源, 前端素材对应, 文件位置, 重新导出
|
||||
|
||||
### Community 38 - "TinyYolov2Base"
|
||||
Cohesion: 0.19
|
||||
Nodes (13): convLayer(), convWithBatchNorm(), depthwiseSeparableConv$1(), fullyConnectedLayer(), leaky(), ONet(), PNet(), prelu() (+5 more)
|
||||
### 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
|
||||
@@ -319,25 +321,25 @@ Nodes (10): boundary(), day(), format(), milliseconds(), range(), shifted(), ass
|
||||
Cohesion: 0.18
|
||||
Nodes (11): list, bounds(), layer_at(), main(), save_image(), composite(), main(), sha256() (+3 more)
|
||||
|
||||
### Community 43 - ".run"
|
||||
Cohesion: 0.22
|
||||
Nodes (3): ComputeAllFaceDescriptorsTask(), ComputeSingleFaceDescriptorTask(), extendWithFaceDescriptor()
|
||||
### Community 43 - "extractAllFacesAndComputeResults"
|
||||
Cohesion: 0.12
|
||||
Nodes (8): ComputeAllFaceDescriptorsTask(), ComputeSingleFaceDescriptorTask(), extendWithFaceDescriptor(), extendWithFaceExpressions(), extractAllFacesAndComputeResults(), extractSingleFaceAndComputeResult(), PredictAllFaceExpressionsTask(), PredictSingleFaceExpressionsTask()
|
||||
|
||||
### Community 44 - "start-local.sh"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): HOST, PORT, start-local.sh script
|
||||
|
||||
### Community 45 - "vizCompose"
|
||||
Cohesion: 0.14
|
||||
Nodes (14): esc(), openHistory(), renderHistoryList(), renderReport(), renderViz(), setDim(), vizCollectMarks(), vizCompose() (+6 more)
|
||||
### Community 45 - "head-pose.js"
|
||||
Cohesion: 0.33
|
||||
Nodes (8): assertPoints(), check(), clamp(), dist(), estimate(), makeFrontal(), makeSide(), midpoint()
|
||||
|
||||
### Community 46 - ".forwardInput"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): boxPredictionLayer(), decodeBoxesLayer(), depthwiseConvLayer(), getCenterCoordinatesAndSizesLayer(), getStridesForLayerIdx(), mobileNetV1(), outputLayer(), pointwiseConvLayer() (+1 more)
|
||||
|
||||
### Community 47 - "e"
|
||||
Cohesion: 0.19
|
||||
Nodes (13): Bo(), ca(), cl(), e(), fa(), Kf(), pa(), rn() (+5 more)
|
||||
### Community 47 - ".toString"
|
||||
Cohesion: 0.20
|
||||
Nodes (7): FaceLandmarks5(), FaceMatch(), getCenterPoint(), la(), pr(), pt(), vt()
|
||||
|
||||
### Community 48 - "已修改"
|
||||
Cohesion: 0.22
|
||||
@@ -364,8 +366,8 @@ Cohesion: 0.60
|
||||
Nodes (5): diffCtx(), loadJSON(), main(), okNum(), okStr()
|
||||
|
||||
### Community 58 - ".forwardInput"
|
||||
Cohesion: 0.17
|
||||
Nodes (10): FaceRecognitionNet(), iou(), NetInput(), nonMaxSuppression(), nonMaxSuppression$1(), scale(), SsdMobilenetv1(), stage1() (+2 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (8): iou(), NetInput(), nonMaxSuppression(), nonMaxSuppression$1(), scale(), stage1(), stage2(), stage3()
|
||||
|
||||
### Community 61 - "报告布局与跟手交互调整"
|
||||
Cohesion: 0.33
|
||||
@@ -399,12 +401,12 @@ Nodes (7): assert, end, fs, path, source, start, vm
|
||||
Cohesion: 0.29
|
||||
Nodes (3): errors, samples, unexpectedWrites
|
||||
|
||||
### Community 77 - "drawFaceExpressions"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): drawFaceExpressions(), FaceExpressions(), isWithFaceExpressions()
|
||||
### Community 77 - "vizCompose"
|
||||
Cohesion: 0.14
|
||||
Nodes (14): esc(), openHistory(), renderHistoryList(), renderReport(), renderViz(), setDim(), vizCollectMarks(), vizCompose() (+6 more)
|
||||
|
||||
### Community 78 - "height"
|
||||
Cohesion: 0.38
|
||||
Cohesion: 0.32
|
||||
Nodes (5): height(), FaceLandmark68NetBase(), getSizesForScale(), normalize$1(), rescaleAndNormalize()
|
||||
|
||||
### Community 79 - "登录反馈与加载优化(2026-10-12)"
|
||||
@@ -444,36 +446,40 @@ 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.24
|
||||
Nodes (10): Ci(), Ei(), Fi(), Ii(), ki(), pe(), ri(), ve() (+2 more)
|
||||
Cohesion: 0.28
|
||||
Nodes (9): Ci(), Ei(), Fi(), Ii(), ki(), pe(), ri(), wi() (+1 more)
|
||||
|
||||
### Community 92 - "客户反馈修改(2026-10-12)"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): 公网部署与复测, 客户反馈修改(2026-10-12), 皱纹数据说明, 逐项处理, 验证
|
||||
|
||||
### Community 93 - "k"
|
||||
Cohesion: 0.23
|
||||
Nodes (12): ba(), bf(), cf(), da(), h(), k(), ll(), xa() (+4 more)
|
||||
### 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 96 - "i"
|
||||
Cohesion: 0.10
|
||||
Nodes (20): b(), bn(), dn(), ee(), et(), fn(), i(), je() (+12 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (36): b(), ba(), bn(), ca(), da(), dn(), ee(), et() (+28 more)
|
||||
|
||||
### Community 97 - "account-client.js"
|
||||
Cohesion: 0.53
|
||||
Nodes (8): browser(), clearGuestCache(), ensureGuest(), guest(), init(), logout(), rememberKind(), request()
|
||||
|
||||
### Community 98 - ".runAndExtendWithFaceDetections"
|
||||
Cohesion: 0.20
|
||||
Nodes (8): DetectAllFacesTask(), DrawBox(), drawDetections(), DrawFaceLandmarks(), extendWithFaceDetection(), isWithFaceDetection(), isWithFaceLandmarks(), resizeResults()
|
||||
### Community 98 - "drawFaceExpressions"
|
||||
Cohesion: 0.22
|
||||
Nodes (6): DrawBox(), drawDetections(), drawFaceExpressions(), DrawFaceLandmarks(), FaceExpressions(), isWithFaceExpressions()
|
||||
|
||||
### Community 99 - "normalize"
|
||||
Cohesion: 0.14
|
||||
Nodes (15): conv(), conv$1(), convDown(), convLayer$1(), convNoRelu(), denseBlock3(), denseBlock4(), depthwiseSeparableConv() (+7 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (26): conv(), conv$1(), convDown(), convLayer(), convLayer$1(), convNoRelu(), convWithBatchNorm(), denseBlock3() (+18 more)
|
||||
|
||||
### Community 100 - ".runAndExtendWithFaceDetection"
|
||||
Cohesion: 0.33
|
||||
@@ -483,9 +489,9 @@ Nodes (5): allFacesMtcnn(), allFacesSsdMobilenetv1(), allFacesTinyYolov2(), dete
|
||||
Cohesion: 0.50
|
||||
Nodes (3): crypto, fs, path
|
||||
|
||||
### Community 102 - "wechat-browser.mjs"
|
||||
Cohesion: 0.22
|
||||
Nodes (6): createAccounts, h5, ReportUI, require, root, SkinScore
|
||||
### Community 102 - "report-persistence.mjs"
|
||||
Cohesion: 0.29
|
||||
Nodes (6): child, dataRoot, fx, h5, ReportUI, require
|
||||
|
||||
### Community 107 - "基础信息记忆与肤质拖动"
|
||||
Cohesion: 0.40
|
||||
@@ -511,21 +517,17 @@ Nodes (7): assert, descriptions, missing, SS, templates, UI, v
|
||||
Cohesion: 0.40
|
||||
Nodes (4): 后台和历史, 痘痘按三视图各类型最大数量计分, 规则, 验证
|
||||
|
||||
### Community 116 - "extractAllFacesAndComputeResults"
|
||||
Cohesion: 0.14
|
||||
Nodes (9): extendWithAge(), extendWithFaceExpressions(), extendWithGender(), extractAllFacesAndComputeResults(), extractSingleFaceAndComputeResult(), PredictAllAgeAndGenderTask(), PredictAllFaceExpressionsTask(), PredictSingleAgeAndGenderTask() (+1 more)
|
||||
|
||||
### Community 117 - "initialize"
|
||||
Cohesion: 0.29
|
||||
Nodes (7): createBrowserEnv(), createFileSystem(), createNodejsEnv(), initialize(), isBrowser(), monkeyPatch(), setEnv()
|
||||
### Community 116 - "age"
|
||||
Cohesion: 0.13
|
||||
Nodes (6): age(), extendWithAge(), extendWithGender(), FaceExpressionNet(), PredictAllAgeAndGenderTask(), PredictSingleAgeAndGenderTask()
|
||||
|
||||
### Community 118 - "f"
|
||||
Cohesion: 0.21
|
||||
Nodes (21): a(), d(), drawContour(), dt(), ea(), f(), g(), jf() (+13 more)
|
||||
Cohesion: 0.20
|
||||
Nodes (24): a(), cf(), d(), drawContour(), dt(), ea(), f(), g() (+16 more)
|
||||
|
||||
### Community 120 - "disposeUnusedWeightTensors"
|
||||
Cohesion: 0.09
|
||||
Nodes (23): disposeUnusedWeightTensors(), extractorsFactory$3(), extractorsFactory$5(), extractorsFactory$7(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$1(), extractParamsFromWeigthMap$2() (+15 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 122 - "doCapture"
|
||||
Cohesion: 0.14
|
||||
@@ -547,6 +549,10 @@ Nodes (8): child, profile, projected, raw, require, root, SS, UI
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 修改, 后台北京时间统一, 验证
|
||||
|
||||
### Community 129 - "报告底部 Figma 还原"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 报告底部 Figma 还原, 静态素材核对, 验证
|
||||
|
||||
### Community 130 - "wrinkle-overall.js"
|
||||
Cohesion: 0.25
|
||||
Nodes (6): assert, base, changed, onlyOverall, SS, UI
|
||||
@@ -555,18 +561,22 @@ Nodes (6): assert, base, changed, onlyOverall, SS, UI
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 原始肌龄显示与鸿蒙滚轮兼容, 回归, 范围
|
||||
|
||||
### Community 133 - "FaceLandmarks68"
|
||||
Cohesion: 0.13
|
||||
Nodes (6): FaceLandmarks5(), FaceLandmarks68(), getCenterPoint(), Point(), pt(), vt()
|
||||
|
||||
### Community 135 - "恢复321与色斑案例复测"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 恢复321与色斑案例复测, 拍摄提示音, 真实色斑案例
|
||||
|
||||
### Community 136 - "js/profile-store.js"
|
||||
Cohesion: 0.67
|
||||
Nodes (3): clean(), create(), key()
|
||||
|
||||
### Community 137 - "皱纹改用接口整体评分"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): 案例复算, 皱纹改用接口整体评分, 验证
|
||||
|
||||
### Community 139 - ".mul"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): wl(), wn(), xn()
|
||||
|
||||
### Community 142 - "tone-dark-circle.js"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): a, assert, near(), SS, UI
|
||||
@@ -576,19 +586,19 @@ Cohesion: 0.40
|
||||
Nodes (4): 图像, 用户确认的评分口径, 肤色项加入黑眼圈20%,色素图30%叠加, 验证
|
||||
|
||||
## Knowledge Gaps
|
||||
- **416 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+411 more)
|
||||
- **418 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+413 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.
|
||||
|
||||
## Suggested Questions
|
||||
_Questions this graph is uniquely positioned to answer:_
|
||||
|
||||
- **Why does `height()` connect `height` to `app.js`, `customer-feedback.js`, `extractFaces`, `scan-placeholder.mjs`, `__awaiter`, `profile-interaction.mjs`, `showScreen`, `getEnv`, `.forwardInput`?**
|
||||
_High betweenness centrality (0.052) - this node is a cross-community bridge._
|
||||
- **Why does `r()` connect `n` to `face-api.js`, `normalize`, `server.js`, `e`, `f`, `C`, `k`?**
|
||||
_High betweenness centrality (0.036) - this node is a cross-community bridge._
|
||||
- **Why does `n()` connect `n` to `face-api.js`, `i`, `skin-score.js`, `server.js`, `e`, `acne-three-view.js`, `f`, `C`, `k`?**
|
||||
_High betweenness centrality (0.036) - this node is a cross-community bridge._
|
||||
- **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 `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._
|
||||
- **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?**
|
||||
@@ -596,4 +606,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?**
|
||||
_416 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
_418 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
File diff suppressed because one or more lines are too long
+664
-564
File diff suppressed because it is too large
Load Diff
+40
-10
@@ -40,8 +40,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/app.js": {
|
||||
"mtime": 1791993770.7910676,
|
||||
"ast_hash": "8cb340dfb0d29d7cd83cf4e0aab0c163",
|
||||
"mtime": 1791997508.305589,
|
||||
"ast_hash": "18a46103211b61bc28411752adc49133",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/head-pose.js": {
|
||||
@@ -140,8 +140,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/index.html": {
|
||||
"mtime": 1791993770.7910676,
|
||||
"ast_hash": "f3c662c2976d141a844328daaf6269f3",
|
||||
"mtime": 1791997577.3025386,
|
||||
"ast_hash": "d643e8ee571d51ed6e61c8a3fc70dedd",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/vendor/faceapi/README.md": {
|
||||
@@ -1245,8 +1245,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/js/report-ui.js": {
|
||||
"mtime": 1791993447.323378,
|
||||
"ast_hash": "aeadd6c859fc41db9931a04b01bbda16",
|
||||
"mtime": 1791997508.305589,
|
||||
"ast_hash": "ef6df0e12065dfc4d157494891038268",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/lib/accounts.js": {
|
||||
@@ -1695,8 +1695,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/customer-feedback-third.mjs": {
|
||||
"mtime": 1791815038.0630124,
|
||||
"ast_hash": "32560625a79f7c8a9d7b74de7337729c",
|
||||
"mtime": 1791997644.8472245,
|
||||
"ast_hash": "58089e992930098527cf51a3f45ace98",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"tools/export_third_feedback_assets.py": {
|
||||
@@ -1975,8 +1975,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/guest-privacy.mjs": {
|
||||
"mtime": 1791878787.1969805,
|
||||
"ast_hash": "b6143cba8c2aff80dd5c4687208b9f36",
|
||||
"mtime": 1791997759.4912488,
|
||||
"ast_hash": "11848a289d0bebe297820d6e237af8d4",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/wechat-fixture.cjs": {
|
||||
@@ -2128,5 +2128,35 @@
|
||||
"mtime": 1791993479.4296343,
|
||||
"ast_hash": "d883b001f777509857a96f02b872a6de",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/test/report-bottom-figma.mjs": {
|
||||
"mtime": 1791998797.7419598,
|
||||
"ast_hash": "81af5b52ef2b0b1d14f9ffb6159f2d3a",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/\u62a5\u544a\u5e95\u90e8Figma\u8fd8\u539f-2026-10-15.md": {
|
||||
"mtime": 1791998656.0611603,
|
||||
"ast_hash": "ce4a94e4026ebc2c410f76f361a24ca1",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/img/ui-20261015/product-25.png": {
|
||||
"mtime": 1791997501.3216276,
|
||||
"ast_hash": "0a1542dbb3c5feb3267fafb1df3123f7",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/img/ui-20261015/product-35.png": {
|
||||
"mtime": 1791997504.752126,
|
||||
"ast_hash": "ff34af3a983eefe9ec93802a525b4ed5",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/img/ui-20261015/product-50.png": {
|
||||
"mtime": 1791997508.2898638,
|
||||
"ast_hash": "9e0d71ba4397d9dbbec27b1ad48fbe9a",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"h5/assets/img/ui-20261015/product-badge.png": {
|
||||
"mtime": 1791997415.2784162,
|
||||
"ast_hash": "4ec7b754fe30aac6248e7f8f990ac078",
|
||||
"semantic_hash": ""
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 391 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 407 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 496 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
+28
-1
@@ -82,6 +82,33 @@
|
||||
.prod-scroll { flex: 0 0 51.219512%; }
|
||||
.prod-scroll img { width: 100%; height: 100%; aspect-ratio: auto; object-fit: fill; }
|
||||
|
||||
/* Figma 1:65, 1080px canvas. One algorithm-selected product, not a catalogue. */
|
||||
/* User-confirmed: both lines centered; use the same font size/line height
|
||||
as the stability heading rather than scaling text on wide previews. */
|
||||
.prod-title { width:calc(206.597222 * var(--u)); max-width:100%; text-align:center; margin:calc(13 * var(--u)) auto calc(8.583333 * var(--u)); padding:0; transform:translateX(calc(.347222 * var(--u))); font-size:22.106597px; line-height:28.738542px; font-weight:700; white-space:nowrap; }
|
||||
.report-care-products { width:calc(340.625 * var(--u)); margin-left:auto; margin-right:auto; padding:calc(21.180556 * var(--u)) calc(24.652778 * var(--u)) calc(7.986111 * var(--u)); }
|
||||
.report-care-products .card-heading,
|
||||
.product-section-heading { font-size:13.888889px; line-height:19.444444px; font-weight:700; text-align:left; }
|
||||
.report-care-products .card-heading { margin-bottom:calc(5.208333 * var(--u)); }
|
||||
.report-care-products .care-item { font-size:11.574074px; line-height:14.467593px; margin-bottom:calc(14.467593 * var(--u)); }
|
||||
.report-care-products .care-item:last-child { margin-bottom:0; }
|
||||
.product-section-heading { margin:calc(34.375 * var(--u)) 0 calc(5.555556 * var(--u)); }
|
||||
.report-care-products .card-product { width:auto; margin:0 calc(-18.402778 * var(--u)); border-radius:calc(3.472222 * var(--u)); background:#F6F6F6; }
|
||||
.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 .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. */
|
||||
#p-analyzing { background: #000; overflow: hidden; }
|
||||
@@ -134,7 +161,7 @@
|
||||
#stat-score { display: flex; align-items: baseline; justify-content: center; }
|
||||
#stat-score b { display: block; letter-spacing: 0; }
|
||||
#stat-score i { position: static; margin-left: 2px; }
|
||||
.card-care .card-heading { text-align: left; margin-bottom: calc(9 * var(--u)); }
|
||||
.card-care:not(.report-care-products) .card-heading { text-align: left; margin-bottom: calc(9 * var(--u)); }
|
||||
|
||||
/* The profile is a fixed page, not a scroll container. Keep normal-height PSD
|
||||
spacing; shrink only vertical whitespace/photo height on shorter viewports.
|
||||
|
||||
+10
-15
@@ -238,8 +238,8 @@
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
<h2 class="dimension-title">稳韧力</h2>
|
||||
<div class="card card-detail">
|
||||
<h2 class="dimension-title dimension-stability-title">稳韧力</h2>
|
||||
<div class="card card-detail stability-card">
|
||||
<div class="detail-tabs"><button class="dtab active" data-tab="0"><span class="dtab-tx">泛红</span></button><button class="dtab" data-tab="1"><span class="dtab-tx">痘痘</span></button></div>
|
||||
<div class="detail-viewport"><div class="detail-panels">
|
||||
<div class="dpanel active" data-panel="0">
|
||||
@@ -254,33 +254,28 @@
|
||||
</div>
|
||||
<p class="vm-notes" id="vm-notes" style="display:none"></p>
|
||||
|
||||
<p class="report-disclaimer">*您的肌肤状态会随年龄、环境、作息和生活节奏动态变化。<br>*本次检测仅代表当前肌肤状态参考。</p>
|
||||
|
||||
<div class="card card-care">
|
||||
<h2 class="card-heading">护理建议</h2>
|
||||
<h2 class="prod-title">感受高光时刻<br>从日常的好状态开始</h2>
|
||||
<div class="card card-care report-care-products">
|
||||
<h2 class="card-heading">日常护理</h2>
|
||||
<div id="care-list">
|
||||
<p class="care-item">检测完成后显示分析结果。</p>
|
||||
</div>
|
||||
<p class="care-summary">好状态,是内外同调的长期节奏。</p>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 产品推荐大标题独立于白卡之外,直接落在灰底上(Figma 08) -->
|
||||
<h2 class="prod-title">感受高光时刻<br>从日常的好状态开始</h2>
|
||||
<h2 class="product-section-heading">推荐产品</h2>
|
||||
<p id="product-unavailable" class="care-item" hidden>本次未获取有效肌龄,暂无法推荐产品,建议重新检测。</p>
|
||||
<div class="card card-product">
|
||||
<div class="card-product">
|
||||
<div class="prod-card">
|
||||
<div class="prod-info">
|
||||
<h3 id="product-title"></h3>
|
||||
<p class="prod-name" id="product-name"></p>
|
||||
<img class="prod-badge" src="assets/img/ui-20261009/product-badge.png" alt="1’me">
|
||||
<img class="prod-badge" src="assets/img/ui-20261015/product-badge.png" alt="1’me">
|
||||
</div>
|
||||
<div class="prod-scroll" id="prod-scroll">
|
||||
<img id="product-image" alt="算法推荐精华">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p class="report-disclaimer">*您的肌肤状态会随年龄、环境、作息和生活节奏动态变化。<br>*本次检测仅代表当前肌肤状态参考。<br>*仅根据您最近的测肤记录推荐。</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+8
-9
@@ -1556,20 +1556,19 @@
|
||||
}).join('') || '<p class="care-item">本次有效数据不足,暂无个性化护理建议。</p>';
|
||||
var product = presentation.product;
|
||||
$('.card-product').hidden = !product;
|
||||
$('.prod-title').hidden = !product;
|
||||
$('#product-unavailable').hidden = !!product;
|
||||
if (product) {
|
||||
$('#product-title').textContent = product.title;
|
||||
$('#product-name').replaceChildren();
|
||||
[product.name, '双仓精华液'].forEach(function (line) {
|
||||
var span = document.createElement('span'); span.className = 'product-line'; span.textContent = line;
|
||||
$('#product-name').appendChild(span);
|
||||
});
|
||||
// Presentation snapshots retain historical copy/recommendations. Only the
|
||||
// artwork crop is refreshed by tier, without mutating stored report data.
|
||||
// product display/artwork is refreshed by selected tier, never re-selected.
|
||||
var productArt = ReportUI.products.filter(function (p) { return p.tier === product.tier; })[0];
|
||||
$('#product-title').textContent = productArt ? productArt.title : product.title;
|
||||
$('#product-name').textContent = productArt ? productArt.name : product.name;
|
||||
$('#product-image').src = productArt ? productArt.image : product.image;
|
||||
$('#product-image').alt = product.name + '双仓精华液';
|
||||
$('#product-image').alt = (productArt ? productArt.title : product.title) + '推荐产品';
|
||||
} else {
|
||||
$('#product-image').removeAttribute('src');
|
||||
$('#product-title').textContent = '';
|
||||
$('#product-name').textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -10,9 +10,9 @@
|
||||
['sens', '泛红', 'stab', 'sens'], ['acne', '痘痘', 'stab', 'acne']
|
||||
];
|
||||
var products = [
|
||||
{ tier: 1, match: '25+束紧精华', title: "1'me 主场精华 I", name: '以我本然有光蓄活', image: 'assets/img/ui-20261012/product-25.jpg' },
|
||||
{ tier: 2, match: '35+支撑精华', title: "1'me 主场精华 II", name: '以我自在有势挺括', image: 'assets/img/ui-20261012/product-35.jpg' },
|
||||
{ tier: 3, match: '50+重塑精华', title: "1'me 主场精华 III", name: '以我从容有态构塑', image: 'assets/img/ui-20261012/product-50.jpg' }
|
||||
{ tier: 1, match: '25+束紧精华', title: "1'me 主场精华 I", name: '焕活光泽 透亮紧致', image: 'assets/img/ui-20261015/product-25.png' },
|
||||
{ tier: 2, match: '35+支撑精华', title: "1'me 主场精华 II", name: '恢复弹性 紧实利落', image: 'assets/img/ui-20261015/product-35.png' },
|
||||
{ tier: 3, match: '50+重塑精华', title: "1'me 主场精华 III", name: '强韧屏障 轮廓向上', image: 'assets/img/ui-20261015/product-50.png' }
|
||||
];
|
||||
var levelMap = { '预警': '改善', '改善': '良好', '良好': '优秀' };
|
||||
var dimNames = { firm: '紧塑力', vita: '透亮感', stab: '稳韧力' };
|
||||
|
||||
@@ -171,18 +171,18 @@ try {
|
||||
await route.fulfill({ response, body: await response.text() + '\nMOCK_FIXTURE.result.skin_age = { value: ' + age + ' };' });
|
||||
});
|
||||
await page.goto(base + '?mock=1&screen=report'); await loadFonts();
|
||||
await page.waitForFunction(() => document.querySelector('#product-image').naturalWidth === 504);
|
||||
assert((await page.locator('#product-image').getAttribute('src')).endsWith('product-' + ({ 1: 25, 2: 35, 3: 50 }[tier]) + '.jpg'));
|
||||
await page.waitForFunction(() => document.querySelector('#product-image').naturalWidth === 481);
|
||||
assert((await page.locator('#product-image').getAttribute('src')).endsWith('product-' + ({ 1: 25, 2: 35, 3: 50 }[tier]) + '.png'));
|
||||
for (const width of widths) {
|
||||
await page.setViewportSize({ width, height: 844 });
|
||||
await page.locator('.card-product').scrollIntoViewIfNeeded();
|
||||
const info = await rect('.prod-info'), name = await rect('#product-name'), title = await rect('#product-title');
|
||||
assert(title.right <= info.right && name.right <= info.right, 'product text overlaps art at ' + width + ': ' + JSON.stringify({ info, name, title }));
|
||||
assert(Math.abs(title.x - info.x - 26.736111) < .1);
|
||||
assert.equal(await page.locator('#product-name').evaluate(e => getComputedStyle(e).fontWeight), '600');
|
||||
assert.equal((await actualLines('#product-name')).length, 2);
|
||||
assert(Math.abs(title.x - info.x - 81 / 1080 * width) < .1);
|
||||
assert.equal(await page.locator('#product-name').evaluate(e => getComputedStyle(e).fontWeight), '700');
|
||||
assert.equal((await actualLines('#product-name')).length, 1);
|
||||
const card = await rect('.card-product');
|
||||
assert(Math.abs(card.width - 984 / 1080 * width) < .1, 'exact PSD card width');
|
||||
assert(Math.abs(card.width - 945 / 1080 * width) < .1, 'exact current Figma card width');
|
||||
assert(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth));
|
||||
}
|
||||
await page.setViewportSize({ width: 375, height: 726 }); await screenshot('05-product-' + tier, '.card-product');
|
||||
|
||||
@@ -129,10 +129,10 @@ try {
|
||||
const heading = el.querySelector('.card-heading'), body = el.querySelector('#care-list');
|
||||
return { margin: parseFloat(getComputedStyle(heading).marginBottom), gap: body.getBoundingClientRect().top - heading.getBoundingClientRect().bottom };
|
||||
});
|
||||
assert(Math.abs(spacing.margin - 9) < .1 && Math.abs(spacing.gap - 9) < 1, 'care title gap is halved from 18px to 9px');
|
||||
assert(Math.abs(spacing.margin - 5.208333) < .1 && Math.abs(spacing.gap - 5.208333) < 1, 'daily care title gap follows current Figma');
|
||||
if (artifacts) await page.locator('.card-care').screenshot({ path: path.join(artifacts, 'care-spacing.png') });
|
||||
assert.deepEqual(errors, []);
|
||||
console.log('PASS: four-character bold/underlined privacy link, half care gap; guest success/failure no disk writes or saved history/identity; WeChat retains snapshots/photos/admin records; screenshots; no paid calls');
|
||||
console.log('PASS: four-character bold/underlined privacy link, current Figma care gap; guest success/failure no disk writes or saved history/identity; WeChat retains snapshots/photos/admin records; screenshots; no paid calls');
|
||||
} finally {
|
||||
if (browser) await browser.close();
|
||||
if (child.exitCode == null) { const stopped = once(child, 'exit'); child.kill(); await stopped; }
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// Figma 1:65 visual layout, synthetic reports; no backend writes or paid calls.
|
||||
import assert from 'node:assert/strict';import fs from 'node:fs';import path from 'node:path';
|
||||
import {execSync} from 'node:child_process';import{fileURLToPath,pathToFileURL}from'node:url';
|
||||
const{chromium}=await import(pathToFileURL(execSync('npm root -g',{encoding:'utf8'}).trim()+'/playwright/index.mjs').href);
|
||||
const browser=await chromium.launch();const artifacts=process.env.H5_ARTIFACT_DIR;
|
||||
if(artifacts)fs.mkdirSync(artifacts,{recursive:true});
|
||||
try{
|
||||
const p=await browser.newPage({viewport:{width:375,height:1400},isMobile:true,hasTouch:true});const errors=[];
|
||||
p.on('pageerror',e=>errors.push(e.message));
|
||||
await p.route('**/api/**',r=>{assert.equal(r.request().method(),'GET');return r.fulfill({json:{ok:true,user:{kind:'browser'}}});});
|
||||
const source=fs.readFileSync(fileURLToPath(new URL('../js/app.js',import.meta.url)),'utf8');
|
||||
await p.route('**/js/app.js*',r=>r.fulfill({contentType:'text/javascript',body:source.replace(/\}\)\(\);\s*$/,`
|
||||
window.__bottomTest=function(age,legacy){
|
||||
var raw=JSON.parse(JSON.stringify(MOCK_FIXTURE.result));
|
||||
if(age==null)delete raw.skin_age;else raw.skin_age={value:age};
|
||||
var vm=SkinScore.buildViewModel(raw,MOCK_FIXTURE.side,{realAge:30});
|
||||
var presentation=JSON.parse(JSON.stringify(ReportUI.build(vm,raw)));
|
||||
if(legacy&&presentation.product){presentation.product.name='旧版名称';presentation.product.image='missing-legacy.png';}
|
||||
var before=JSON.stringify(presentation);
|
||||
renderReport(vm,MOCK_FIXTURE.photos[0],null,{result:raw,presentation:presentation});showScreen('s-report');
|
||||
return {before:before,after:JSON.stringify(presentation),tier:presentation.product&&presentation.product.tier};
|
||||
};
|
||||
})();`)}));
|
||||
await p.goto((process.env.H5_BASE_URL||'http://127.0.0.1:8080/')+'?mock=1&screen=report');
|
||||
await p.evaluate(()=>document.fonts.ready);
|
||||
const names=['焕活光泽 透亮紧致','恢复弹性 紧实利落','强韧屏障 轮廓向上'];
|
||||
for(const[age,tier]of[[24,1],[40,2],[60,3]]){
|
||||
const state=await p.evaluate(age=>window.__bottomTest(age,true),age);assert.equal(state.tier,tier);assert.equal(state.before,state.after);
|
||||
await p.waitForFunction(()=>document.querySelector('#product-image').complete&&document.querySelector('#product-image').naturalWidth===481);
|
||||
assert.equal(await p.locator('#product-name').textContent(),names[tier-1]);
|
||||
assert.equal(await p.locator('.card-product:visible').count(),1);
|
||||
assert.equal(await p.locator('.report-care-products .card-product').count(),1);
|
||||
assert.equal(await p.locator('.report-care-products .card-heading').textContent(),'日常护理');
|
||||
assert.equal(await p.locator('.product-section-heading').textContent(),'推荐产品');
|
||||
assert.equal(await p.locator('.care-summary').count(),0);
|
||||
assert((await p.locator('.report-disclaimer').textContent()).includes('仅根据您最近的测肤记录推荐'));
|
||||
for(const width of[320,375,414,480]){
|
||||
await p.setViewportSize({width,height:1400});await p.locator('.card-product').scrollIntoViewIfNeeded();
|
||||
const geo=await p.evaluate(()=>{
|
||||
const rect=s=>{const r=document.querySelector(s).getBoundingClientRect();return{x:r.x,y:r.y,w:r.width,h:r.height,right:r.right,bottom:r.bottom};};
|
||||
return{heading:rect('.prod-title'),care:rect('.card-care'),product:rect('.card-product'),info:rect('.prod-info'),title:rect('#product-title'),name:rect('#product-name'),image:rect('#product-image'),badge:rect('.prod-badge'),disclaimer:rect('.report-disclaimer'),align:getComputedStyle(document.querySelector('.prod-title')).textAlign,headingFont:parseFloat(getComputedStyle(document.querySelector('.prod-title')).fontSize)};
|
||||
});
|
||||
assert.equal(geo.align,'center');assert(geo.heading.bottom<=geo.care.y+1);
|
||||
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');
|
||||
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');
|
||||
assert(Math.abs(geo.product.w/geo.product.h-945/511)<.01);
|
||||
assert(Math.abs(geo.image.w/geo.image.h-481/511)<.01);
|
||||
assert(Math.abs(geo.badge.w/geo.badge.h-101/77)<.01);
|
||||
assert(await p.evaluate(()=>document.documentElement.scrollWidth<=innerWidth));
|
||||
}
|
||||
await p.setViewportSize({width:375,height:1400});await p.locator('.card-product').scrollIntoViewIfNeeded();
|
||||
if(artifacts){
|
||||
const top=await p.locator('.prod-title').evaluate(e=>e.getBoundingClientRect().top);
|
||||
const end=await p.locator('.report-disclaimer').evaluate(e=>e.getBoundingClientRect().bottom);
|
||||
await p.screenshot({path:path.join(artifacts,'report-bottom-'+tier+'.png'),clip:{x:0,y:Math.max(0,top-8),width:375,height:end-Math.max(0,top-8)+8}});
|
||||
}
|
||||
}
|
||||
await p.evaluate(()=>window.__bottomTest(null,false));
|
||||
assert.equal(await p.locator('.card-product').isVisible(),false);assert(await p.locator('#product-unavailable').isVisible());
|
||||
assert(await p.locator('.card-care').isVisible());assert(await p.locator('.prod-title').isVisible());
|
||||
assert.equal(await p.locator('#product-image').getAttribute('src'),null);
|
||||
// Long actual advice must push the product down rather than overlap it.
|
||||
await p.evaluate(()=>{window.__bottomTest(24,false);document.querySelector('#care-list').textContent='测试长建议。'.repeat(300);});
|
||||
const safe=await p.evaluate(()=>document.querySelector('#care-list').getBoundingClientRect().bottom<=document.querySelector('.product-section-heading').getBoundingClientRect().top);assert(safe);
|
||||
assert.deepEqual(errors,[]);console.log('PASS bottom: 3 selected products, 4 widths, exact image ratios, merged card, titles/disclaimer order, legacy recommendation immutable, missing/long content');
|
||||
}finally{await browser.close();}
|
||||
Reference in New Issue
Block a user