feat(h5): align October UI and add WeChat auth with saved reports

This commit is contained in:
xsl
2026-10-11 17:28:11 +08:00
parent ee744b6b5f
commit ce8d0ff1f7
126 changed files with 18711 additions and 1898 deletions
+42
View File
@@ -0,0 +1,42 @@
# UI 外发版 10.09 图片资源
来源:用户提供的 `UI外发版10.09.psd`。按 Photoshop 图层原样导出,未重新生成或重绘素材。
## 文件位置
- `pages/`:10 个画板的原尺寸 PNG,宽 1080px。包含登录、启动、授权弹窗、我的报告、档案填写、拍照弹窗、三视图拍照及长报告。
- `pages-overview.jpg`:全部页面缩略总览,按 PSD 原始画板顺序排列。
- `assets-overview.jpg`:独立切图总览。
- `manifest.json`:页面与切图的尺寸、文件名、图层索引、边界、可见状态及 SHA-256;同时保存完整图层树及文字,便于后续还原。
- `../../h5/assets/img/ui-20261009/`:新版页面使用的独立图片,与旧版素材分开存放。H5 使用去除原生顶栏的 `*-h5.jpg` 衍生背景。
## 前端素材对应
| 文件 | 用途 |
| --- | --- |
| `bg-splash.jpg` | 启动页原始照片,不含独立标题、Logo 与按钮 |
| `bg-profile.jpg` / `bg-login.jpg` | 档案页 / 登录页背景,按画板裁剪,保留设计里的叠色 |
| `bg-report.jpg` / `bg-history.jpg` | 长报告 / 我的报告页纯背景,按画板裁剪 |
| `skin-0-dry.png` … `skin-4-mixedoily.png` | 五档肤质插画;也导出了隐藏状态中的变体 |
| `product-25.png` / `product-35.png` / `product-50.png` | 三档产品图,分别取对应产品组中的主视觉图层 |
| `brand-*.png` / `product-badge.png` | 品牌标志与产品标志 |
| `icon-*.png` | 关闭、返回、下拉、相册、切换相机、快门、微信、游客图标 |
| `score-ring-*.png` | 设计稿中的评分环参考素材;实际评分仍应动态绘制 |
| `camera-mask-front.png` / `camera-mask-right.png` / `camera-mask-left.png` | 三步拍照轮廓蒙版,保留画板坐标与透明区域 |
| `camera-guide-front.png` / `camera-guide-right.png` / `camera-guide-left.png` | 对应三步的眼睛与鼻梁虚线定位叠层,与蒙版使用相同画板坐标 |
| `sample-*.png` | 设计稿内检测示意图,仅供视觉参考,不代替用户真实检测图 |
照片使用高质量渐进 JPG;其他素材使用 PNG 保留透明通道。切图按原图层尺寸输出,不强行放大,不将文字与按钮烘焙进背景。整页预览保留设计稿原有系统状态栏和重复/隐藏图层状态。
`sample-lines.png` 来自隐藏的备选示意图层,设计文件内各分类存在重复示意图,文件名不表示图片已经过该项目评分引擎的真实检测。产品图按主视觉独立导出,卡片圆角和裁剪需由前端容器实现。
注意:PSD 的画板名「左面」实际文案为第 2 步「右脸出镜」,「右面」实际文案为第 3 步「左脸出镜」。切图按文案中的用户脸部方向命名,清单保存了对应图层路径。
## 重新导出
```bash
python -m pip install psd-tools Pillow aggdraw
python tools/export_psd_assets.py '/absolute/path/UI外发版10.09.psd'
```
重新导出会更新本版本目录内的导出文件,不会覆盖 `h5/assets/img/` 下原有同名线上图片。
Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

@@ -0,0 +1,780 @@
{
"viewport": {
"width": 375,
"height": 726
},
"pages": {
"01-splash": {
"screen": "s-splash",
"text": "Life in Full\n为更好的生命表现\n\n肌肤状态检测\n开始检测",
"overlays": [],
"rects": [
{
"class": "splash-slogan",
"rect": {
"x": 0,
"y": 77.671875,
"width": 375,
"height": 63.46875,
"top": 77.671875,
"right": 375,
"bottom": 141.140625,
"left": 0
}
},
{
"class": "splash-bottom",
"rect": {
"x": 0,
"y": 551.984375,
"width": 375,
"height": 84,
"top": 551.984375,
"right": 375,
"bottom": 635.984375,
"left": 0
}
}
]
},
"02-privacy": {
"screen": "s-splash",
"text": "Life in Full\n为更好的生命表现\n\n肌肤状态检测\n开始检测",
"overlays": [
{
"id": "p-privacy",
"text": "欢迎体验1'me\n肌肤状态评估服务!\n\n我们将采集您的面部影像,为您生成专属肌肤分析与状态管理方案。所有数据严格保密,仅用于本次检测分析。\n\n我已阅读并同意相关隐私协议\n继续"
}
],
"rects": [
{
"class": "splash-slogan",
"rect": {
"x": 0,
"y": 77.671875,
"width": 375,
"height": 63.46875,
"top": 77.671875,
"right": 375,
"bottom": 141.140625,
"left": 0
}
},
{
"class": "splash-bottom",
"rect": {
"x": 0,
"y": 551.984375,
"width": 375,
"height": 84,
"top": 551.984375,
"right": 375,
"bottom": 635.984375,
"left": 0
}
}
]
},
"03-profile": {
"screen": "s-profile",
"text": "您的肌肤状态\n您的出生年月\n您的性别\n您的所在地区\n您的日常肤质\n偏干\n偏油\n水油平衡\n干性肌肤\n\n全脸干燥,容易紧绷、缺乏光泽\n\n混合偏干肌肤\n\n两颊偏干,T区油脂较少或偶尔出油\n\n中性肌肤\n\n水油平衡,肤感舒适,无明显干燥出油\n\n油性肌肤\n\n全脸易出油,容易泛油光、毛孔明显\n\n混合偏油肌肤\n\nT区易出油,两颊相对清爽或轻微干燥\n\n提交",
"overlays": [],
"rects": [
{
"class": "profile-body",
"rect": {
"x": 0,
"y": 0,
"width": 375,
"height": 726,
"top": 0,
"right": 375,
"bottom": 726,
"left": 0
}
},
{
"class": "page-title",
"rect": {
"x": 64,
"y": 34,
"width": 247,
"height": 31,
"top": 34,
"right": 311,
"bottom": 65,
"left": 64
}
}
]
},
"04-guide": {
"screen": "s-profile",
"text": "您的肌肤状态\n您的出生年月\n1996年1月\n您的性别\n女\n您的所在地区\n北京市\n您的日常肤质\n偏干\n偏油\n水油平衡\n干性肌肤\n\n全脸干燥,容易紧绷、缺乏光泽\n\n混合偏干肌肤\n\n两颊偏干,T区油脂较少或偶尔出油\n\n中性肌肤\n\n水油平衡,肤感舒适,无明显干燥出油\n\n油性肌肤\n\n全脸易出油,容易泛油光、毛孔明显\n\n混合偏油肌肤\n\nT区易出油,两颊相对清爽或轻微干燥\n\n提交",
"overlays": [
{
"id": "p-photoguide",
"text": "Life in Full\n为更好的生命表现\n\n请拍摄或上传\n正面及左右侧面照片\n开始"
}
],
"rects": [
{
"class": "profile-body",
"rect": {
"x": 0,
"y": 0,
"width": 375,
"height": 726,
"top": 0,
"right": 375,
"bottom": 726,
"left": 0
}
},
{
"class": "page-title",
"rect": {
"x": 64,
"y": 34,
"width": 247,
"height": 31,
"top": 34,
"right": 311,
"bottom": 65,
"left": 64
}
}
]
},
"05-camera-front": {
"screen": "s-cam",
"text": "1/3\n请正对屏幕\n\n检测引擎加载中…\n\n识别不到?请正对镜头,并到光线充足处\n\n正脸拍摄完成\n准备拍摄下一张\n正脸居中\n取下眼镜\n光线充足",
"overlays": [],
"rects": [
{
"class": "cam-step",
"rect": {
"x": 0,
"y": 51.53125,
"width": 375,
"height": 64.5,
"top": 51.53125,
"right": 375,
"bottom": 116.03125,
"left": 0
}
},
{
"class": "cam-guide",
"rect": {
"x": 0,
"y": 542.390625,
"width": 375,
"height": 21,
"top": 542.390625,
"right": 375,
"bottom": 563.390625,
"left": 0
}
},
{
"class": "cam-controls",
"rect": {
"x": 0,
"y": 626.25,
"width": 375,
"height": 62,
"top": 626.25,
"right": 375,
"bottom": 688.25,
"left": 0
}
}
]
},
"06-camera-right": {
"screen": "s-cam",
"text": "1/3\n请正对屏幕\n\n检测引擎加载中…\n\n识别不到?请正对镜头,并到光线充足处\n\n正脸拍摄完成\n准备拍摄下一张\n正脸居中\n取下眼镜\n光线充足",
"overlays": [],
"rects": [
{
"class": "cam-step",
"rect": {
"x": 0,
"y": 51.53125,
"width": 375,
"height": 64.5,
"top": 51.53125,
"right": 375,
"bottom": 116.03125,
"left": 0
}
},
{
"class": "cam-guide",
"rect": {
"x": 0,
"y": 542.390625,
"width": 375,
"height": 21,
"top": 542.390625,
"right": 375,
"bottom": 563.390625,
"left": 0
}
},
{
"class": "cam-controls",
"rect": {
"x": 0,
"y": 626.25,
"width": 375,
"height": 62,
"top": 626.25,
"right": 375,
"bottom": 688.25,
"left": 0
}
}
]
},
"07-camera-left": {
"screen": "s-cam",
"text": "2/3\n请右脸出镜\n\n检测引擎加载中…\n\n识别不到?请正对镜头,并到光线充足处\n\n正脸拍摄完成\n下一张:右脸出镜\n请向左转头\n右脸居中\n取下眼镜\n光线充足",
"overlays": [],
"rects": [
{
"class": "cam-step",
"rect": {
"x": 0,
"y": 51.53125,
"width": 375,
"height": 64.5,
"top": 51.53125,
"right": 375,
"bottom": 116.03125,
"left": 0
}
},
{
"class": "cam-guide",
"rect": {
"x": 0,
"y": 542.390625,
"width": 375,
"height": 21,
"top": 542.390625,
"right": 375,
"bottom": 563.390625,
"left": 0
}
},
{
"class": "cam-controls",
"rect": {
"x": 0,
"y": 626.25,
"width": 375,
"height": 62,
"top": 626.25,
"right": 375,
"bottom": 688.25,
"left": 0
}
}
]
},
"08-report-top": {
"screen": "s-report",
"text": "您的肌肤状态表现\n70分\n综合评分\n肌肤年龄\n27岁\n比实际年龄年轻1岁\n紧塑力\n7.7\n优先关注\n活力感\n8.7\n稳定力\n9.1\n近期优先关注:紧塑力\n紧塑提拉力,轮廓上扬不松垮。\n紧塑力\n活力感\n稳定力\n轮廓\n\n下颌线角度左104.54°/右103.75°(标准区间116–120°,双侧均偏离标准,提示下颌缘支撑力下降);眼袋1级、黑眼圈1级;中面部支撑与轮廓清晰度处于预警水平。建议加强轮廓紧致护理:重点针对下颌线与下颌缘区域使用紧致类精华,配合由下向上的提拉按摩手法,同时加强眼周支撑护理,将紧致防线前置。\n\n皱纹\n\n全脸皱纹159条、细纹150条,最差区域为左嘴角纹(分区分77,最高严重度3级),部分区域已现静态纹趋势。建议针对眼周、法令纹等高发区使用视黄醇/胜肽类淡纹精华,遏制静态纹转化。\n\n*您的肌肤状态会随年龄、环境、作息和生活节奏动态变化。\n*本次检测仅代表当前肌肤状态参考。\n\n护理建议\n\n1、你的日常肤质为干性肌肤:全脸皮脂分泌偏少,角质层保水能力弱,易紧绷起屑。护理以高效保湿与封闭锁水为核心,洁面选用温和低泡产品,避免频繁去角质,面霜可选择含神经酰胺、角鲨烷等封闭性成分的配方。\n\n2、加强纹路分级管理,重点针对眼周、法令纹等动态纹高发区域,使用视黄醇/胜肽类淡纹精华并配合点按手法,遏制静态纹转化。\n\n3、加强细腻度管理,避免过度清洁破坏角质屏障,重点关注毛孔显著区域,配合低浓度酸类(如水杨酸)周期护理与柔润精华。\n\n4、建议搭配使用35+支撑精华:专为轻熟肌打造,提升弹韧表现、维持面部轮廓清晰度,改善疲态并延缓衰老速度。\n\n5、保持侧卧改仰卧的睡姿习惯,减少枕巾摩擦;控制屏幕时间,缓解眼周疲劳\n\n好状态,是内外同调的长期节奏。\n\n精华推荐\n\n35+支撑精华\n\n推荐依据:皱纹得分偏低\n\n感受高光时刻\n从日常的好状态开始\n以我自在有势挺括\n双仓精华液\n\n参透皮下根源 28天校准皮肤状态\n\n了解更多",
"overlays": [],
"rects": [
{
"class": "report-title",
"rect": {
"x": 18,
"y": 0,
"width": 339,
"height": 86,
"top": 0,
"right": 357,
"bottom": 86,
"left": 18
}
},
{
"class": "card card-summary",
"rect": {
"x": 18,
"y": 86,
"width": 339,
"height": 140,
"top": 86,
"right": 357,
"bottom": 226,
"left": 18
}
},
{
"class": "card card-dims",
"rect": {
"x": 18,
"y": 238,
"width": 339,
"height": 201.1875,
"top": 238,
"right": 357,
"bottom": 439.1875,
"left": 18
}
},
{
"class": "card card-detail",
"rect": {
"x": 18,
"y": 451.1875,
"width": 339,
"height": 334.96875,
"top": 451.1875,
"right": 357,
"bottom": 786.15625,
"left": 18
}
},
{
"class": "card card-care",
"rect": {
"x": 18,
"y": 852.15625,
"width": 339,
"height": 510,
"top": 852.15625,
"right": 357,
"bottom": 1362.15625,
"left": 18
}
},
{
"class": "card card-essence",
"rect": {
"x": 18,
"y": 1374.15625,
"width": 339,
"height": 119.5,
"top": 1374.15625,
"right": 357,
"bottom": 1493.65625,
"left": 18
}
},
{
"class": "card card-product",
"rect": {
"x": 18,
"y": 1608.34375,
"width": 339,
"height": 215.671875,
"top": 1608.34375,
"right": 357,
"bottom": 1824.015625,
"left": 18
}
}
]
},
"09-report-tab-0": {
"screen": "s-report",
"text": "您的肌肤状态表现\n70分\n综合评分\n肌肤年龄\n27岁\n比实际年龄年轻1岁\n紧塑力\n7.7\n优先关注\n活力感\n8.7\n稳定力\n9.1\n近期优先关注:紧塑力\n紧塑提拉力,轮廓上扬不松垮。\n紧塑力\n活力感\n稳定力\n轮廓\n\n下颌线角度左104.54°/右103.75°(标准区间116–120°,双侧均偏离标准,提示下颌缘支撑力下降);眼袋1级、黑眼圈1级;中面部支撑与轮廓清晰度处于预警水平。建议加强轮廓紧致护理:重点针对下颌线与下颌缘区域使用紧致类精华,配合由下向上的提拉按摩手法,同时加强眼周支撑护理,将紧致防线前置。\n\n皱纹\n\n全脸皱纹159条、细纹150条,最差区域为左嘴角纹(分区分77,最高严重度3级),部分区域已现静态纹趋势。建议针对眼周、法令纹等高发区使用视黄醇/胜肽类淡纹精华,遏制静态纹转化。\n\n*您的肌肤状态会随年龄、环境、作息和生活节奏动态变化。\n*本次检测仅代表当前肌肤状态参考。\n\n护理建议\n\n1、你的日常肤质为干性肌肤:全脸皮脂分泌偏少,角质层保水能力弱,易紧绷起屑。护理以高效保湿与封闭锁水为核心,洁面选用温和低泡产品,避免频繁去角质,面霜可选择含神经酰胺、角鲨烷等封闭性成分的配方。\n\n2、加强纹路分级管理,重点针对眼周、法令纹等动态纹高发区域,使用视黄醇/胜肽类淡纹精华并配合点按手法,遏制静态纹转化。\n\n3、加强细腻度管理,避免过度清洁破坏角质屏障,重点关注毛孔显著区域,配合低浓度酸类(如水杨酸)周期护理与柔润精华。\n\n4、建议搭配使用35+支撑精华:专为轻熟肌打造,提升弹韧表现、维持面部轮廓清晰度,改善疲态并延缓衰老速度。\n\n5、保持侧卧改仰卧的睡姿习惯,减少枕巾摩擦;控制屏幕时间,缓解眼周疲劳\n\n好状态,是内外同调的长期节奏。\n\n精华推荐\n\n35+支撑精华\n\n推荐依据:皱纹得分偏低\n\n感受高光时刻\n从日常的好状态开始\n以我自在有势挺括\n双仓精华液\n\n参透皮下根源 28天校准皮肤状态\n\n了解更多",
"overlays": [],
"rects": [
{
"class": "report-title",
"rect": {
"x": 18,
"y": -60,
"width": 339,
"height": 86,
"top": -60,
"right": 357,
"bottom": 26,
"left": 18
}
},
{
"class": "card card-summary",
"rect": {
"x": 18,
"y": 26,
"width": 339,
"height": 140,
"top": 26,
"right": 357,
"bottom": 166,
"left": 18
}
},
{
"class": "card card-dims",
"rect": {
"x": 18,
"y": 178,
"width": 339,
"height": 201.1875,
"top": 178,
"right": 357,
"bottom": 379.1875,
"left": 18
}
},
{
"class": "card card-detail",
"rect": {
"x": 18,
"y": 391.1875,
"width": 339,
"height": 334.96875,
"top": 391.1875,
"right": 357,
"bottom": 726.15625,
"left": 18
}
},
{
"class": "card card-care",
"rect": {
"x": 18,
"y": 792.15625,
"width": 339,
"height": 510,
"top": 792.15625,
"right": 357,
"bottom": 1302.15625,
"left": 18
}
},
{
"class": "card card-essence",
"rect": {
"x": 18,
"y": 1314.15625,
"width": 339,
"height": 119.5,
"top": 1314.15625,
"right": 357,
"bottom": 1433.65625,
"left": 18
}
},
{
"class": "card card-product",
"rect": {
"x": 18,
"y": 1548.34375,
"width": 339,
"height": 215.671875,
"top": 1548.34375,
"right": 357,
"bottom": 1764.015625,
"left": 18
}
}
]
},
"09-report-tab-1": {
"screen": "s-report",
"text": "您的肌肤状态表现\n70分\n综合评分\n肌肤年龄\n27岁\n比实际年龄年轻1岁\n紧塑力\n7.7\n优先关注\n活力感\n8.7\n稳定力\n9.1\n近期优先关注:紧塑力\n紧塑提拉力,轮廓上扬不松垮。\n紧塑力\n活力感\n稳定力\n光滑\n\n皮肤表面平整度较低,最差毛孔区位于额头(分区毛孔分32),粗大毛孔1041颗、黑头113颗,T区出油面积57%、左右脸颊20%/2%,纹理分仅82,整体细腻度不足。建议避免过度清洁,重点关注额头,配合低浓度酸类周期护理与柔润精华。\n\n肤色水润\n\n肤色ITA 58.6(极白,HA 56.2),色素分92,整体稳定但存在局部暗沉倾向(未见明显色斑标记,检出褐色斑37处);水分分78,缺水面积19.8%、严重度22。建议加强抗氧化与光泽管理,做好基础防晒与补水。\n\n*您的肌肤状态会随年龄、环境、作息和生活节奏动态变化。\n*本次检测仅代表当前肌肤状态参考。\n\n护理建议\n\n1、你的日常肤质为干性肌肤:全脸皮脂分泌偏少,角质层保水能力弱,易紧绷起屑。护理以高效保湿与封闭锁水为核心,洁面选用温和低泡产品,避免频繁去角质,面霜可选择含神经酰胺、角鲨烷等封闭性成分的配方。\n\n2、加强纹路分级管理,重点针对眼周、法令纹等动态纹高发区域,使用视黄醇/胜肽类淡纹精华并配合点按手法,遏制静态纹转化。\n\n3、加强细腻度管理,避免过度清洁破坏角质屏障,重点关注毛孔显著区域,配合低浓度酸类(如水杨酸)周期护理与柔润精华。\n\n4、建议搭配使用35+支撑精华:专为轻熟肌打造,提升弹韧表现、维持面部轮廓清晰度,改善疲态并延缓衰老速度。\n\n5、保持侧卧改仰卧的睡姿习惯,减少枕巾摩擦;控制屏幕时间,缓解眼周疲劳\n\n好状态,是内外同调的长期节奏。\n\n精华推荐\n\n35+支撑精华\n\n推荐依据:皱纹得分偏低\n\n感受高光时刻\n从日常的好状态开始\n以我自在有势挺括\n双仓精华液\n\n参透皮下根源 28天校准皮肤状态\n\n了解更多",
"overlays": [],
"rects": [
{
"class": "report-title",
"rect": {
"x": 18,
"y": -60,
"width": 339,
"height": 86,
"top": -60,
"right": 357,
"bottom": 26,
"left": 18
}
},
{
"class": "card card-summary",
"rect": {
"x": 18,
"y": 26,
"width": 339,
"height": 140,
"top": 26,
"right": 357,
"bottom": 166,
"left": 18
}
},
{
"class": "card card-dims",
"rect": {
"x": 18,
"y": 178,
"width": 339,
"height": 201.1875,
"top": 178,
"right": 357,
"bottom": 379.1875,
"left": 18
}
},
{
"class": "card card-detail",
"rect": {
"x": 18,
"y": 391.1875,
"width": 339,
"height": 306.53125,
"top": 391.1875,
"right": 357,
"bottom": 697.71875,
"left": 18
}
},
{
"class": "card card-care",
"rect": {
"x": 18,
"y": 763.71875,
"width": 339,
"height": 510,
"top": 763.71875,
"right": 357,
"bottom": 1273.71875,
"left": 18
}
},
{
"class": "card card-essence",
"rect": {
"x": 18,
"y": 1285.71875,
"width": 339,
"height": 119.5,
"top": 1285.71875,
"right": 357,
"bottom": 1405.21875,
"left": 18
}
},
{
"class": "card card-product",
"rect": {
"x": 18,
"y": 1519.90625,
"width": 339,
"height": 215.671875,
"top": 1519.90625,
"right": 357,
"bottom": 1735.578125,
"left": 18
}
}
]
},
"09-report-tab-2": {
"screen": "s-report",
"text": "您的肌肤状态表现\n70分\n综合评分\n肌肤年龄\n27岁\n比实际年龄年轻1岁\n紧塑力\n7.7\n优先关注\n活力感\n8.7\n稳定力\n9.1\n近期优先关注:紧塑力\n紧塑提拉力,轮廓上扬不松垮。\n紧塑力\n活力感\n稳定力\n敏感\n\n泛红面积0.6%,红区分99,屏障状态稳定,未见明显敏感信号。建议维持现有温和护理,避免过度去角质。\n\n痘痘\n\n检出9处皮损(闭口粉刺6处、丘疹3处)。建议尽快进行针对性抗痘护理,避免挤压与刺激,必要时寻求皮肤科专业处理。\n\n*您的肌肤状态会随年龄、环境、作息和生活节奏动态变化。\n*本次检测仅代表当前肌肤状态参考。\n\n护理建议\n\n1、你的日常肤质为干性肌肤:全脸皮脂分泌偏少,角质层保水能力弱,易紧绷起屑。护理以高效保湿与封闭锁水为核心,洁面选用温和低泡产品,避免频繁去角质,面霜可选择含神经酰胺、角鲨烷等封闭性成分的配方。\n\n2、加强纹路分级管理,重点针对眼周、法令纹等动态纹高发区域,使用视黄醇/胜肽类淡纹精华并配合点按手法,遏制静态纹转化。\n\n3、加强细腻度管理,避免过度清洁破坏角质屏障,重点关注毛孔显著区域,配合低浓度酸类(如水杨酸)周期护理与柔润精华。\n\n4、建议搭配使用35+支撑精华:专为轻熟肌打造,提升弹韧表现、维持面部轮廓清晰度,改善疲态并延缓衰老速度。\n\n5、保持侧卧改仰卧的睡姿习惯,减少枕巾摩擦;控制屏幕时间,缓解眼周疲劳\n\n好状态,是内外同调的长期节奏。\n\n精华推荐\n\n35+支撑精华\n\n推荐依据:皱纹得分偏低\n\n感受高光时刻\n从日常的好状态开始\n以我自在有势挺括\n双仓精华液\n\n参透皮下根源 28天校准皮肤状态\n\n了解更多",
"overlays": [],
"rects": [
{
"class": "report-title",
"rect": {
"x": 18,
"y": -60,
"width": 339,
"height": 86,
"top": -60,
"right": 357,
"bottom": 26,
"left": 18
}
},
{
"class": "card card-summary",
"rect": {
"x": 18,
"y": 26,
"width": 339,
"height": 140,
"top": 26,
"right": 357,
"bottom": 166,
"left": 18
}
},
{
"class": "card card-dims",
"rect": {
"x": 18,
"y": 178,
"width": 339,
"height": 201.1875,
"top": 178,
"right": 357,
"bottom": 379.1875,
"left": 18
}
},
{
"class": "card card-detail",
"rect": {
"x": 18,
"y": 391.1875,
"width": 339,
"height": 303,
"top": 391.1875,
"right": 357,
"bottom": 694.1875,
"left": 18
}
},
{
"class": "card card-care",
"rect": {
"x": 18,
"y": 760.1875,
"width": 339,
"height": 510,
"top": 760.1875,
"right": 357,
"bottom": 1270.1875,
"left": 18
}
},
{
"class": "card card-essence",
"rect": {
"x": 18,
"y": 1282.1875,
"width": 339,
"height": 119.5,
"top": 1282.1875,
"right": 357,
"bottom": 1401.6875,
"left": 18
}
},
{
"class": "card card-product",
"rect": {
"x": 18,
"y": 1516.375,
"width": 339,
"height": 215.671875,
"top": 1516.375,
"right": 357,
"bottom": 1732.046875,
"left": 18
}
}
]
},
"splash-375x844": {
"screen": "s-splash",
"text": "Life in Full\n为更好的生命表现\n\n肌肤状态检测\n开始检测",
"overlays": [],
"rects": [
{
"class": "splash-slogan",
"rect": {
"x": 0,
"y": 90.296875,
"width": 375,
"height": 63.46875,
"top": 90.296875,
"right": 375,
"bottom": 153.765625,
"left": 0
}
},
{
"class": "splash-bottom",
"rect": {
"x": 0,
"y": 655.359375,
"width": 375,
"height": 84,
"top": 655.359375,
"right": 375,
"bottom": 739.359375,
"left": 0
}
}
]
},
"splash-390x844": {
"screen": "s-splash",
"text": "Life in Full\n为更好的生命表现\n\n肌肤状态检测\n开始检测",
"overlays": [],
"rects": [
{
"class": "splash-slogan",
"rect": {
"x": 0,
"y": 90.296875,
"width": 390,
"height": 66,
"top": 90.296875,
"right": 390,
"bottom": 156.296875,
"left": 0
}
},
{
"class": "splash-bottom",
"rect": {
"x": 0,
"y": 652.265625,
"width": 390,
"height": 87.09375,
"top": 652.265625,
"right": 390,
"bottom": 739.359375,
"left": 0
}
}
]
},
"splash-414x844": {
"screen": "s-splash",
"text": "Life in Full\n为更好的生命表现\n\n肌肤状态检测\n开始检测",
"overlays": [],
"rects": [
{
"class": "splash-slogan",
"rect": {
"x": 0,
"y": 90.296875,
"width": 414,
"height": 70.0625,
"top": 90.296875,
"right": 414,
"bottom": 160.359375,
"left": 0
}
},
{
"class": "splash-bottom",
"rect": {
"x": 0,
"y": 645.859375,
"width": 414,
"height": 93.5,
"top": 645.859375,
"right": 414,
"bottom": 739.359375,
"left": 0
}
}
]
}
},
"errors": []
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

+55
View File
@@ -0,0 +1,55 @@
# 10.09 新版 H5 实施与验收
更新:2026-10-10。
## 按确认项实现
- 保持 H5,无额外网页导航栏,不仿造系统/微信顶部栏。
- 登录在首页之前;复用现有协议弹层。微信网页授权链路已实现,当前内网使用本机浏览器身份,公网限制与部署见《微信登录接入与公网部署说明》。
- 首页更新口号、背景和品牌图,增加「我的报告」。修正重复入口、出镜错字。
- 我的报告独立页面,数量、日期、查看详情、空/失败状态;读取当前账号最近 5 份后端报告。
- 档案页换用新版背景和五类肤质插画,保留原选择器和校验。
- 相机轮廓与眼鼻定位虚线从 PSD 素材提取,前→右→左流程、自动抓拍、降级、语音和前后摄像头逻辑保持。
- 汇总卡合并,名称为「生物可视年龄」「紧塑力」「透亮感」「稳韧力」,不照抄设计样例中的数值。
- 七项视图分成三个独立 Tab 组:轮廓/皱纹;肤色/平滑度/水分;泛红/痘痘。使用真实检测图层或用户照片,不把设计里的模特检测图当成检测结果。
- 根据 `reference/AI测肤报告页话术修改.md` 生成新结论和护理建议。无效字段不冒充 0,无图层明确说明。
- 只显示原算法选中的一款主场精华 I / II / III,不可点击,移除「了解更多」占位入口。
- MiSans 官方原始 Web 字体本地提供,未改造字体文件;「我的报告」底部注明字体使用。
## 文档未定义部分的实施口径
话术文档没有新增计分公式或阈值,因此原六分类/三维度评分、肌龄计算及精华推荐规则不变。旧分档「预警/改善/良好」按低/中/高顺序映射为新文案的「改善/良好/优秀」。肤色和水分拆分展示,但继续共享原 `tone` 分类的分档,**不是新增独立评分算法**。
痘痘话术按真实脓包/结节计数决定是否输出中重度皮损说明;没有计数不宣称「未检出」。当真实计数与高分模板冲突时,展示层选择可反映计数的文案,不改变原分数。
护理建议按原六分类得分选取最需要关注的两项,拼接文档对应的「护理 + 生活方式」;若命中肤色水润,分别展示肤色与水分建议,可能为三段。设计里的示例两段不作为截断真实文本的硬限制。
历史详情读取保存时的 `vm`、`presentation`、照片、图层,不用当前评分/话术重新生成历史数据。图像合成有渲染版本防护,切换报告时不会串用上一份图片。
## 验证命令
```bash
node h5/js/skin-score.js
node h5/test/regression.js
node h5/test/accounts.js
node h5/test/report-persistence.mjs
node h5/test/wechat-browser.mjs
node h5/test/ui-20261009.mjs
node h5/test/e2e-browser.mjs
```
浏览器测试需要全局 Playwright 与 Chromium,沿用项目既有环境。`ui-20261009.mjs` 默认访问本地 8080,可用 `H5_BASE_URL` 覆盖;`report-persistence.mjs` 单独启用 18089 临时服务和临时数据目录,不写入日常报告,不调用收费 Face++。
本轮结果:评分模块自测 83 条、真值回归 86 条通过;账号隔离、恢复登录、重启持久化、最近 5 条、OAuth state 防重放/子路径检查通过;模拟上游的完整 HTTP 链路验证七张图片及文案刷新回看完全一致;三连拍与语音端到端检查通过;320/390/480px 宽度无横向溢出,浏览器无脚本异常。
截图位于 `design/ui-20261009/verification/`。这些是本地 Chromium/样本数据检查,不等于真实手机摄像头或微信公网账号验收。本轮没有触发真实 Face++ 收费请求。
## 素材再生成
```bash
python tools/export_psd_assets.py /你的路径/UI外发版10.09.psd
python tools/prepare_h5_assets.py
python tools/build_report_copy.py
```
PSD 导出依赖 psd-tools/Pillow/aggdraw;H5 裁剪与相机轮廓提取还使用 numpy/opencv-python。原始导出保留,`*-h5.jpg` 是去除原生顶栏后的衍生背景;相机几何写入 `h5/js/camera-geometry.js`。
+25
View File
@@ -0,0 +1,25 @@
# 提交前 Review(2026-10-11)
范围:10.09 H5 UI、浏览器/微信身份、后端报告快照、部署说明;重点检查公网调试前的访问控制和回调路径。
## 已发现并修复
1. **P1:静态敏感路径可被重复/编码斜杠绕过。** 原先先按原始路径检查 `/data`、`/lib`、`/server.js`,文件读取时才规范化;`/%2fserver.js` 实测返回 200。现统一斜杠并规范化后再授权,额外禁止访问 `JUZI_DATA_ROOT`。新增原始 HTTP 路径测试,覆盖双斜杠、编码斜杠、反斜杠和父目录段;修复后源码路径返回 404,数据目录返回拒绝响应。
2. **P2:nginx 后的用户共用登录限流。** 原限流只看 TCP 对端,代理后全站共用回环地址的每分钟 60 次额度。新增显式 `TRUST_LOOPBACK_PROXY=1`,仅信任回环代理覆盖的合法 `X-Real-IP`;文档同步 nginx 配置。已测试不同 IP 额度独立,以及未启用信任时伪造请求头不能绕过限流。
## 验证
- 评分模块自测:83 通过;真值回归:86 通过。
- 账号/报告:权限隔离、最近 5 份、重启恢复、浏览器凭据恢复、会话退出、OAuth state 绑定和重放检查通过。
- 完整检测 API→保存→回看:使用模拟上游,不调用收费 Face++;七张图片和话术刷新后完全一致。
- UI 与三连拍:协议校验、登录回退、移动端布局、三视角流程、语音均通过。
- `wechat-browser.mjs`:使用临时 HTTPS 证书和 `/state/` 反代路径,验证前端微信按钮→模拟授权站点→服务端回调→Secure/HttpOnly/SameSite Cookie→首页/报告。两个独立浏览器上下文关联同一模拟 OpenID。此测试需要本地 OpenSSL 和 Playwright。
## 仍需公网/业务确认
- 未使用真实微信 AppID/AppSecret 联调,公众号权限、网页授权域名及真实手机回调需在公网验收。
- Node 管理接口仍依赖 nginx Basic Auth,公网只能反代访问,不能暴露 Node 端口。文件存储仅支持单进程。
- 浏览器与微信账号不自动合并;先用本机身份产生的报告不会自动出现在微信账号中。
- 已有协议是 Face++ 隐私政策,品牌方账号关联、报告保留/删除范围仍需业务确认;不应将当前版本视作已完成正式发布合规审核。
提交范围不含真实密钥、`h5/data`、PSD 原稿及 Windows Zone.Identifier 元数据。代码、运行素材、文案来源、测试和部署说明一起提交,便于服务器复现。
@@ -0,0 +1,195 @@
# UI 对齐 10.09 设计稿:调研与实施计划
调研日期:2026-10-10。阶段:调研与计划,尚未修改业务页面。
## 1. 结论和依据
这次更新包括三个层面:既有页面的视觉对齐、报告页的结构重做、新增登录与报告列表流程。仅替换图片不能达到设计稿效果。
依据:
- 最新 PSD:`UI外发版10.09.psd`,10 个画板;采用 `design/ui-20261009/manifest.json` 的图层与文本信息,不再把旧 `design/设计规范.md` 当作新版尺寸依据。
- 实际运行页面:`http://127.0.0.1:8080/?mock=1`。在独立 Chromium 上下文采集启动、授权、档案、拍照引导、三个拍照步骤和报告三组 Tab;另检查 375/390/414px 宽启动页。
- 实测记录:`design/ui-20261009/audit-current/evidence.json`,本轮 15 张截图,未捕获到 JS 页面异常。拍照截图使用 mock/模拟摄像头,不能据此认定手机真实摄像头已通过验证。
- 源码:`h5/index.html`、`h5/css/style.css`、`h5/js/app.js`、`h5/js/skin-score.js`、`h5/server.js` 和浏览器回归脚本。
- 视觉对比:`design/ui-20261009/audit-current/comparison-flow.jpg` 与 `comparison-report.jpg`。每组左侧当前页面、右侧新设计;报告采用不同示例数据,只比较结构与样式,不比较数值与照片内容。
当前技术栈是原生 HTML/CSS/JS + Node 服务。继续沿用即可,没有必要为此次还原引入前端框架。
## 2. 统一比较口径
PSD 标准画板为 1080×2339,报告长页为 1080×7765。375px 宽页面的换算系数为 2.88。
设计顶部约 248px 是系统状态栏与微信标题/胶囊区域。当前 H5 将这块交给浏览器容器,业务页面没有顶部导航。因此本次常规页面对比裁掉该区域,统一为约 375×726 的业务视口;报告顶部按其自身画板标题栏边界约 253px 处理。
建议以「H5 业务内容还原」验收,不在网页里重复绘制电量、时间、信号和小程序胶囊。是否增加网页自己的标题/返回栏需要单独确定;新增一条导航栏会改变所有页面的纵向坐标,不能等页面完成后再决定。
设计实测尺寸(375px 宽基准):
| 元素 | PSD 尺寸 | 换算后尺寸 | 更新要点 |
| --- | --- | --- | --- |
| 首页主/次按钮 | 522×112 | 181.3×38.9 | 当前主按钮高 37px,需统一到新版 |
| 弹窗 | 887×902 | 308.0×313.2 | 统一位置、内边距与文案行距 |
| 弹窗关闭图标 | 51×50 | 17.7×17.4 | 图形按设计大小,触摸区域单独扩大 |
| 档案单列输入框 | 325×112 | 112.8×38.9 | 对齐双列间距、标签间距 |
| 肤质选择卡 | 713×808 | 247.6×280.6 | 配合新插画和文字宽度 |
| 肤质插画 | 316×316 | 109.7×109.7 | 五种状态均已导出 |
| 报告汇总卡 | 982×696 | 341.0×241.7 | 合并当前两张卡 |
| 报告分类卡 | 983×1177 | 341.3×408.7 | 改为大图在上、正文在下 |
| 分类展示图片框 | 619×802 | 214.9×278.5 | 真实照片按比例呈现,标注坐标保持一致 |
| 产品卡 | 984×503 | 341.7×174.7 | 三张卡统一规格 |
这些是基准几何,不代表真实数据页面一律固定高度。长护理建议、缺数据提示等内容应自然撑高,避免截断。
PSD 字体包含 MiSans Regular / Semibold / Demibold;当前 CSS 使用 Noto Sans SC / PingFang / 系统字体,项目未发现配套字体文件。字体会影响换行、数字宽度和字重。实施时优先准备可用于 Web 的对应字体文件,或明确接受系统字体近似。PSD 文本字号还要结合图层变换矩阵计算,不能只读原始 FontSize 就直接换算。
## 3. 逐页差异和调整内容
| 页面 | 当前实现 | 最新设计 | 具体工作 |
| --- | --- | --- | --- |
| 登录 | 无登录页面、无身份状态 | 品牌标志、微信登录、游客登录、协议勾选 | 新增页面与入口状态;游客通路和真实微信认证分别验收 |
| 启动 | 旧口号、单个「开始检测」按钮 | 英文两行 + 中文口号;新增白色「我的报告」按钮 | 更新文案、背景构图、Logo/按钮间距,增加历史入口 |
| 隐私授权 | 直接覆盖当前首页,仍露出首页口号和按钮 | 遮罩底图没有首页交互内容 | 采用独立背景层;校准弹窗位置、字号、关闭图标和勾选行 |
| 档案填写 | 结构基本完整,旧肤质插画;表单整体偏下,背景构图不同 | 相同字段与轮播,但几何、字重、背景不同 | 复用选择器与字段校验,重新标定间距、卡片、五种插画和底部按钮 |
| 拍照引导 | 旧口号;标题居中;没有环境要求说明 | 新口号;标题左对齐;补充关闭美颜/滤镜和均匀光线说明 | 更新背景、标题与说明,校准按钮位置 |
| 三步拍照 | 旧脸型轮廓,无眼鼻虚线;首步「请正对屏幕」 | 新脸型、眼鼻虚线;首步「请正脸出境」 | 更新蒙版及定位线,文案建议纠正为「出镜」;复核前后镜头方向 |
| 我的报告 | 存在隐藏历史弹层逻辑,没有可点击入口 | 独立页面,数量卡、日期列表、查看详情 | 将历史展示升级为页面,接通首页入口、返回和详情打开;补空列表状态 |
| 报告汇总 | 总分/肌龄一张卡,三维度另一张;额外肌龄差、关注说明 | 总分、年龄、三维度在同一张卡 | 合并 DOM 与间距;显示名改为紧塑力/透亮感/稳韧力,处理设计未显示的说明 |
| 报告详情 | 一个全局三维度 Tab,每页两个小图+侧边文字 | 三个纵向区块,每块自有分类 Tab,大图+下方文字 | 重构为独立区块及 Tab 状态,增加肤色/水分两个展示视图 |
| 护理建议 | 五段动态文案和额外结尾句 | 设计只示意两段 | 对齐卡片和排版,保留动态文案;内容长度不能照示例硬截成两段 |
| 产品推荐 | 额外精华推荐卡;固定一张 CORE II 产品图;「了解更多」占位按钮 | 主场精华 I/II/III 三张产品卡 | 三档素材/商品文案配置化;保留真实推荐逻辑,收敛重复模块 |
实测的报告上半部分:当前总分卡 339×140,三维度卡约 339×201,中间有 12px 间隔;设计是一张约 341×242 的卡。这是明显的结构差异,靠缩字体和调颜色无法解决。
当前首页和档案页的背景使用同一张图加 CSS 叠色;新版已导出独立背景,但不能把带叠色的 JPG 再叠一遍旧渐变,否则会过暗。背景和相机蒙版还需根据业务视口裁剪,不能直接把全画板 2339px 高图片拉伸到去掉顶部栏后的 2091px 区域。
## 4. 报告数据如何接到新 UI
建议增加展示适配层,例如 `h5/js/report-ui.js`。评分模块继续产出已有计算结果,适配层负责新版名称、分类视图、图片和商品展示,不把显示名写回数据库或评分公式。
| 新 UI | 已有数据 | 展示适配 |
| --- | --- | --- |
| 紧塑力 | `vm.dims.firm` | 保留该维度评分 |
| 透亮感 | `vm.dims.vita` | 将「活力感」映射为新显示名,包括相关关注提示 |
| 稳韧力 | `vm.dims.stab` | 将「稳定力」映射为新显示名 |
| 轮廓 | `vm.cats.contour` + 正脸照 | 大图及该分类文案 |
| 皱纹 | `vm.cats.wrinkles` + `texture_enhanced_lines` | 保留增强线与原照片合成 |
| 肤色 | `vm.cats.tone` 中肤色相关数据 + `brown_area` | 从合并分类中独立展示,须明确专属文案来源 |
| 平滑度 | `vm.cats.smooth` + 已有标记/图层 | 改名并复用图像合成 |
| 水分 | `vm.cats.tone` 中水分相关数据 + `water_area` | 独立图像/说明,不能声称新增了一项独立评分 |
| 泛红 | `vm.cats.sens` + `red_area` | 显示名与红区合成图更新 |
| 痘痘 | `vm.cats.acne` + 痤疮标记 | 复用坐标叠加 |
当前服务端已经请求并保留 `brown_area` 和 `water_area`。当前 UI 的 `tone` 只展示水分图,因此图库接口不是主要阻碍;需要增加图片容器、展示配置及缺失图层状态。
现有 `tone` 评分合并肤色与水分,话术也是合并话术。新版的七个图片视图,不应自动变成七分类评分。肤色和水分的独立文字应由确定的字段/模板产生;不能把同一段合并文案复制到两个 Tab 后视为完成。
产品映射建议使用明确的配置表:已有「25+束紧精华 / 35+支撑精华 / 50+重塑精华」对应主场精华 I / II / III 的名称、图片和说明。实际推荐由已有多项判据决定,不能只按年龄选择。三张卡可以按设计全部展示;是否强调推荐卡应另定,避免擅自在设计上增加标签。
重构图片异步加载时增加报告/视图版本标记,避免快速切 Tab 或历史报告后,较早的图片合成回调覆盖新页面。
## 5. 登录与“我的报告”的真实能力缺口
目前只有静态页面、检测 API、管理 API 与健康检查,没有面向用户的登录、会话或个人报告接口。管理后台记录不等于个人报告库,不能直接将后台查询接口接到“我的报告”。
本机历史:`juzi.reports.v1`,最多 5 条,存储三张照片与结果,主动删除 `face_maps` 以减少容量。代码可打开旧报告,但图层类图片回看会降级。因而“恢复入口”可以复用较多代码,“跨设备完整回看”则需要新增服务端能力。
建议分两个可验收阶段:
1. **游客闭环**:登录页游客入口 → 首页 → 检测 / 我的报告 → 详情。本地报告列表如实表达当前保留数量,补空态、损坏记录、存储失败和返回行为。图层不全时明确缺失,不能用设计示例人脸补齐。
2. **账号闭环**:明确微信公众号/H5 实际运行容器及可用配置后接入真实登录;建立会话、报告 owner 归属、用户范围内列表/详情/图片读取、退出及游客数据衔接。设计稿自身不能提供这些接口契约。
第二阶段尚未落地前,不能把微信按钮接成“点击即登录成功”。希望完整实现设计中的微信登录功能,需要纳入后端和账号配置工作,而不只是 UI 工期。
若要求游客也能完整回看,需要另选客户端持久化渲染缩略图/IndexedDB,或以受限凭据查询服务端结果;在明确存储策略前,不把大幅 base64 图层直接塞回现有 localStorage。
## 6. 原稿中需要整理的内容
以下来自对 PSD 可见图层及代码契约的核对,不能无条件当成正式需求:
- 首页底部存在重复的「我的报告」文字图层,建议只保留一枚有效按钮。
- 首步「请正脸出境」建议修正为「请正脸出镜」;报告标题多余的右括号、历史数量文案中的重复字也需校正。
- 画板名「左面」文案是第 2 步右脸,「右面」文案是第 3 步左脸。以用户脸部语义和送检字段为准,不按画板名机械替换。
- PSD 范例里有 5.1 分,但现行 S = 7 + 3×P/100 的正常 0–100 输入对应 7–10 分。5.1 只是设计示例;若它代表新评分规则,需独立修改业务契约。
- 设计复用了检测示意图与描述,不能据此让所有真实分类显示同一张图或同一段话。
- 两段护理建议与三张商品卡属于展示示例,需保留真实文案和推荐判据。
- 新登录页列出用户协议、隐私政策、儿童保护政策;当前只有已有隐私弹层内容,缺少新入口各自明确的文本对应。实施时须确定已有文本的覆盖范围和最终链接。
## 7. 实施顺序与交付物
### P0:冻结视觉和数据基准
- 确定 H5 顶栏口径、流程入口、字体,以及上面的设计示例处理方式。
- 按画板重新整理 `--u`、卡片宽、间距、圆角、按钮高、字号和色值。
- 复核 36 张切图:背景裁剪、透明边缘、产品剪贴边界;拍照眼鼻定位线应保留原稿虚线效果,不能只依赖可能近似的 PSD 矢量栅格结果。
- 建立固定的视觉测试数据和「缺图/空态」样例,与真实评分数据分开。
- 交付:新版尺寸表、素材映射、显示字段映射、确定的页面路由。
### P1:公共样式与既有入口流程
- 修改 `h5/css/style.css` 公共组件与背景策略。
- 修改 `h5/index.html` 首页/授权/档案/拍照引导结构,接入新版素材。
- 修改 `h5/js/app.js` 文案、肤质图片配置和相应入口,保留档案选择器校验。
- 交付:首页、授权、档案和引导弹窗的并排截图与可操作流程。
### P2:报告页重构(视觉改动最大)
- 合并汇总卡;显示层统一三个新维度名称。
- 将一个三维度 Tab 改成三个纵向区块,各自包含 2 / 3 / 2 个分类 Tab。
- 大图、分隔线、正文、免责声明、护理建议按新版排版。
- 接入 `brown_area`/`water_area` 视图及独立文案,处理加载/缺失状态。
- 三档产品列表配置化;按定稿移除旧布局的多余块与无实际动作的按钮。
- 主要文件:`index.html`、`style.css`、`app.js`,新增展示适配模块;不因换名改评分引擎。
- 交付:完整长报告、七个视图、三种商品结果和缺数据状态。
### P3:拍照页视觉校准
- 更新三套轮廓与眼鼻定位线,统一使用同一套 viewBox/坐标系。
- 同步裁剪范围、前后镜头镜像、扫描区域、轮廓成功提示;继续使用现有脸部检测和自动抓拍流程。
- 保留实时自动模式和系统相机/相册降级模式;不能因为设计隐藏快门就删除降级模式的快门。
- 交付:三步静态对照、真实摄像头全流程和 HTTP 降级验证。
### P4:登录外观与本机历史闭环
- 新增 `s-login` 与 `s-history`;统一返回栈和刷新行为。
- 游客入口接入首页,“我的报告”显示真实保留数量、日期与详情。
- 为新/旧记录定义兼容读取及缺图策略;退出相机、关闭放大图、回到列表都要返回正确位置。
- 登录图上无法确定授权后跳转、重复授权等状态,按明确的流程方案补齐。
- 交付:游客用户可完整走通;微信入口状态与真实后端能力一致。
### P5:真实账号能力(依赖账号与后端范围确定)
- 登录接入、会话、记录归属及用户级报告 API;补齐跨设备历史和对应权限验证。
- 同步处理退出、授权取消、会话失效和游客报告迁移策略。
- 交付:真实微信登录及本人报告查询。完成此阶段才能把所有设计功能视为完成。
### P6:联合验收与部署
- 固定 375px 基准截图,对照去除原生顶栏的 PSD;再检查 390/414px 及短屏、长屏、底部安全区。
- 静态结构完成后核对字体、图片裁剪、Tab 下划线、卡片边缘和垂直节奏。
- 更新现有 `h5/test/e2e-browser.mjs`:新版入口、独立 Tab、列表详情返回、七图、三商品、无空引用和无 JS 异常。
- 跑 `h5/test/regression.js`;同一测试数据的现有评分/护理建议/推荐结果应保持一致。
- 实机验证微信内 H5、Android 浏览器、iOS 浏览器;现有局域网 HTTP 只能验证降级拍照,实时自动相机需在可用的 HTTPS 环境验证。
- 交付:最终对照图、回归结果、可访问页面地址及尚未覆盖的设备范围。
## 8. 验收定义
1. **结构**:10 个设计画板对应的页面/弹层均有明确落点;新增登录与报告列表不能只是无法操作的截图。
2. **视觉**:375px 固定视口下,静态主要边界目标误差不超过约 2 CSS px;同字体、同文本、同图片才能做局部像素差比较。不同真实数据不得按整页像素误差判断。
3. **响应式**:375/390/414px 下无横向溢出、文字截断、底部按钮被安全区遮挡;长报告允许内容自然增长。
4. **交互**:三块报告 Tab 相互独立,图片点开/返回正常,历史列表与详情可往返,返回不重新启动摄像头。
5. **数据**:七个展示视图与六分类计算关系清晰;姓名/日期/数量/分数来自真实状态;不会加载上一个报告的图片。
6. **拍照**:正 → 用户右脸 → 用户左脸,API 仍按 front/left/right 正确送检;自动、拒绝权限、相册、系统相机路径分别检查。
7. **历史**:列表计数与保留策略一致,缺图或记录损坏有正确提示;若接账号,必须只读本人记录。
8. **性能**:整页 PNG 与设计示意人脸仅用于验收,业务页面按需加载独立素材;产品图懒加载,避免把 445MB PSD 或大幅设计预览带进页面。
## 9. 实施前需要定下的四个选择
本轮计划不依赖立即答复;进入实现前按以下顺序确定即可:
1. **容器**:沿用当前 H5、去除原生顶栏,还是补一条网页标题/返回栏?建议沿用 H5 口径。
2. **账号范围**:先完成游客及本机历史、再接微信,还是把真实登录和跨设备报告纳入同一批交付?两者的后端工作量明显不同。
3. **业务口径**:是否同意三维度仅改显示名、六分类算法保持,肤色/水分拆成展示视图?建议如此,独立话术另行定稿。
4. **原稿整理**:是否按设计保留三商品卡,并去掉旧版额外卡片/占位按钮,同时纠正原稿重复字和错字?建议保留真实推荐信息于护理建议中,清理重复展示。
推荐先完成 P0–P3 的视觉主体,再交付 P4 游客闭环;P5 随账号条件落地。报告结构和新增身份/历史能力是主要工作量,字体和相机坐标是还原精度的主要风险。
@@ -0,0 +1,105 @@
# 微信登录接入与公网部署说明
更新:2026-10-11。当前环境为 Windows 宿主机 + 内网 WSL。
## 结论与当前阻碍
已完成微信网页授权代码,但**没有完成真实微信账号联调**。当前未配置 `WECHAT_APP_ID`、`WECHAT_APP_SECRET`、`PUBLIC_BASE_URL`,也没有可验证的公众号网页授权域名配置。内网 `http://192.168.3.25:8080/` 不能作为本次正式授权部署地址。因此本地启用「本机浏览器登录」,不会模拟微信登录成功。
官方网页授权适用于具有相应权限的认证服务号等账号;需要在公众号后台配置网页授权域名。普通小程序 AppID、开放平台网站应用 AppID 不能直接替代本方案的服务号 AppID。本实现采用 `snsapi_base` 获取 OpenID 做账号关联,不请求头像、昵称。
依据:[微信官方 H5 网页授权文档](https://developers.weixin.qq.com/doc/service/guide/h5/auth.html)(2026-10-10 核对)。实际账号权限和后台配置还需由公众号管理员确认。
## 已完成的链路
1. 登录页先勾选现有协议,再选择微信或本机浏览器登录。
2. 服务端构造授权地址;回调校验一次性 state、浏览器绑定和 10 分钟有效期。
3. 服务端用 code 换取 OpenID,AppSecret 不发送至前端、不写入报告。
4. 同一 AppID + OpenID 对应同一个服务端账号,换手机登录后读取该账号最近 5 份报告。
5. 会话采用 HttpOnly / SameSite=Lax Cookie;公网 HTTPS 配置下附带 Secure。
6. 未配置微信、未在微信浏览器内打开、授权失败时提供明确提示,可选择本机浏览器登录。
自动化测试使用模拟的微信换码响应,已覆盖 state 缺失、绑定错误、重复回调、子路径回调、同一 OpenID 返回同一账号;这些测试不等同于微信真机验收。
## 公网服务器配置
部署整个 `h5/`,包括 `lib/`、`js/report-copy.js`、`js/report-ui.js`、`js/account-client.js`、`js/camera-geometry.js`、新版 CSS、图片和字体。需要 Node 18+,建议沿用当前 Node 22。不能仅部署静态文件。
通过服务管理器的私有环境文件设置以下内容,不放入前端,不提交 Git:
```ini
HOST=127.0.0.1
PORT=8080
# 仅限 Node 绑定回环、nginx 覆盖 X-Real-IP 的部署方式
TRUST_LOOPBACK_PROXY=1
PUBLIC_BASE_URL=https://你的域名/state/
WECHAT_APP_ID=你的认证服务号AppID
WECHAT_APP_SECRET=你的认证服务号AppSecret
SKIN_API_KEY=你的Face++Key
SKIN_API_SECRET=你的Face++Secret
# 可选:独立持久化目录。未设置则使用 h5/data。
JUZI_DATA_ROOT=/var/lib/juzi-h5
```
环境文件权限设为仅服务账号可读,systemd 中使用 `EnvironmentFile=`。重启服务后访问 `.../api/auth/config`,`wechat: true` 只代表必需配置齐备,不代表平台授权已经验收通过。
`PUBLIC_BASE_URL` 必须是用户实际访问的 HTTPS 地址,包含真实子路径。示例回调为:`https://你的域名/state/api/auth/wechat/callback`。公众号后台填写的是域名,不是完整 URL;按后台要求部署域名验证文件到域名根目录。不要向聊天或代码库粘贴 AppSecret。
## 反向代理与后台保护
如果使用 `/state/` 子路径,反向代理要剥离该前缀。以下片段加入已经配置证书的 HTTPS server 中;实际部署前先核对现有 nginx 配置,不要直接覆盖。
```nginx
location = /state { return 301 /state/; }
# 管理后台与用户账号接口相互独立;必须继续保护后台。
location ~ ^/state/(admin\.html|css/admin\.css|js/admin\.js|api/admin/.*)$ {
auth_basic "Juzi Admin";
auth_basic_user_file /etc/nginx/.htpasswd-juzi;
rewrite ^/state/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 20m;
proxy_read_timeout 150s;
}
location /state/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 20m;
proxy_read_timeout 150s;
}
```
根路径部署则设置 `PUBLIC_BASE_URL=https://你的域名/` 并相应去掉上述 `/state/`。不要遗漏 `admin.html` 和 `/api/admin/` 的鉴权,也不要把 Node 8080 直接暴露到公网。现有 Node 管理接口本身不使用新 C 端账号鉴权;公网安全仍依赖后台鉴权和回环监听。
`TRUST_LOOPBACK_PROXY=1` 用于按真实客户端 IP 限制登录频率;只信任来自回环代理且格式合法的 `X-Real-IP`。nginx 必须按示例覆盖该头,不能透传浏览器传入值。本地直接访问时不要启用。未启用时按 TCP 对端限流,在反代后会共享同一计数。
当前 WSL 使用 `HOST=0.0.0.0` 方便局域网测试,局域网内管理接口也可达,请只在可信网络使用。手机 HTTP 访问不是安全相机上下文,会沿用现有系统相机/上传降级;自动实时抓拍需 HTTPS,或在本机 localhost 测试。这与微信授权是否配置是两个不同限制。
## 数据、迁移与备份
- `h5/data/accounts/identities.json`:账号、随机身份凭据的哈希、会话、最近报告索引。
- `h5/data/accounts/reports/<user-id>/<report-id>.json`:完整报告快照,含三张照片、检测图层、评分、话术和推荐产品。
- 原有 `data/records.jsonl`、`data/photos`、`data/results` 继续供后台复核。
- 本机浏览器 localStorage 只保存随机身份凭据,不再存照片与报告。更换设备/浏览器/站点域名,或清除全部站点数据后,不能靠本机身份找回原账号。
- 微信与本机账号不自动合并;旧版 localStorage 报告未自动认领迁移,避免错误关联。旧数据不删除。
- 前台只列出并允许回看最近 5 份,超出 5 份的快照/后台记录暂保留,不代表已物理删除。正式上线需业务方确认保留和删除周期。
- 迁移时停止写入,备份并迁移**完整数据目录**,保留访问权限。只同步代码不会带上报告。禁止将数据目录提交 Git 或由 nginx 作为静态目录公开。
- 当前为单 Node 进程的文件存储,不可对同一目录开多个 worker/多实例;未来扩容需迁移数据库和对象存储。
## 公网真机验收清单
- 微信打开 HTTPS 页面,协议可查看、未勾选不能登录。
- 首次微信登录→首页→三视角检测→我的报告→详情。
- 同一微信账号换另一台手机,能看到原报告;另一微信账号看不到。
- 报告七项检测图与初次生成一致,文案、评分、推荐商品不因回看重算。
- 取消/失败授权后可重新登录或选择本机浏览器登录。
- 重启服务后报告与账号不丢失。
- 检查 HTTPS 摄像头权限、三视角自动抓拍、前后镜头、后台鉴权、数据目录不可访问。
协议处理:登录和检测授权复用 `h5/index.html` 中已有的「Face++ 个人信息与隐私保护政策」(包含儿童相关章节)。本次未发现独立的品牌方用户协议文件,未凭空编写法律条款;正式发布前请业务/法务确认现有政策是否覆盖品牌方的账号关联、报告存储、保存期限和删除渠道。
+43 -35
View File
@@ -1,69 +1,77 @@
{
"0": "face-api.js",
"1": "n",
"1": "t",
"2": "app.js",
"3": "skin-score.js",
"4": "isTensor",
"5": ".toBatchTensor",
"6": "getEnv",
"7": "FaceLandmarks",
"8": "disposeUnusedWeightTensors",
"4": "n",
"5": "normalize",
"6": "drawFaceExpressions",
"7": "Box",
"8": "admin.js",
"9": "__awaiter",
"10": "extractWeightEntryFactory",
"11": "FaceProcessor",
"10": "AgeGenderNet",
"11": "lib/accounts.js",
"12": "server.js",
"13": "files",
"14": "extractAllFacesAndComputeResults",
"14": ".predictAgeAndGender",
"15": ".runAndExtendWithFaceDetection",
"16": "巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范",
"17": "extractFaces",
"18": "1'me 在线肌肤测试 H5",
"19": "head-pose.js",
"20": "build_fixtures.py",
"21": ".forwardInput",
"21": "disposeUnusedWeightTensors",
"22": ".loadFromDisk",
"23": "facepp-skinanalyze(旷视皮肤分析专业版调用技能)",
"24": "巨子测肤 · 1'me 语音播报内容设计文档 V1.0",
"25": "extractParamsFromWeigthMap$1",
"25": "mobile-select.iife.min.js",
"26": "wi",
"27": "gen_voice.py",
"28": "initialize",
"28": "i",
"29": "face-api.js 本地化依赖(h5/vendor/faceapi/)",
"30": "regression.js",
"31": "isValidNumber",
"30": "ui-20261009/manifest.json",
"31": ".toString",
"32": "FaceMatcher",
"33": "build-fixture.py",
"34": "smoke-test.js",
"35": "DetectSingleFaceLandmarksTask",
"36": "so",
"37": "tt",
"36": "C",
"37": "UI 外发版 10.09 图片资源",
"38": "TinyYolov2",
"39": "cn",
"40": ".computeFaceDescriptor",
"41": "SsdMobilenetv1",
"42": "dr",
"39": "UI交互界面调整",
"40": "ComputeAllFaceDescriptorsTask",
"41": ".draw",
"42": "export_psd_assets.py",
"43": "FaceLandmark68Net",
"44": "rescaleAndNormalize",
"44": "start-local.sh",
"45": "PredictAllAgeAndGenderWithFaceAlignmentTask",
"46": "PredictAllFaceExpressionsWithFaceAlignmentTask",
"47": "PredictSingleAgeAndGenderWithFaceAlignmentTask",
"47": "k",
"48": "PredictSingleFaceExpressionsWithFaceAlignmentTask",
"49": "Yo",
"49": "mobile-select/README.md",
"50": "call_skinanalyze_3view.sh",
"51": "TinyXception",
"52": "Vc",
"53": "FaceDetection",
"54": "ff",
"55": "ge",
"56": "sa",
"57": "po",
"51": "第二轮2反馈.md",
"52": "region-data.js",
"53": "护理建议(全量文本,按需求摘抄)",
"54": "UI 对齐 10.09 设计稿:调研与实施计划",
"55": "FaceLandmarks68",
"56": ".forwardInput",
"57": "regression.js",
"58": ".dispose",
"59": "call_skinanalyze.sh",
"60": "report-fixture.js",
"61": ".extractWeights",
"62": "NeuralNetwork",
"61": "NeuralNetwork",
"62": "提交前 Review(2026-10-11)",
"63": "e2e-browser.mjs",
"64": "AgeGenderNet",
"66": "FaceExpressionNet",
"71": "PredictSingleFaceExpressionsTask"
"64": "account-client.js",
"65": "PredictSingleFaceExpressionsTask",
"66": ".runAndExtendWithFaceDetections",
"67": "ui-20261009.mjs",
"68": "ComputeSingleFaceDescriptorTask",
"69": "misans/README.md",
"71": "extractFaceTensors",
"72": "build_report_copy.py",
"73": "camera-geometry.js",
"74": "report-copy.js",
"75": "prepare_h5_assets.py"
}
+1 -1
View File
@@ -1 +1 @@
{"0": "084975bb68797cf4", "1": "6c6ce24229e04595", "2": "64f07a78d61df933", "3": "8ac814cdb72a1a7d", "4": "c18a4a8fab272cc6", "5": "7f62d3cc90a92195", "6": "865611558d18274c", "7": "e7b6c52cb9523ba1", "8": "934b465b2e687d3d", "9": "31a3a505422c0528", "10": "f943c63a37873e9e", "11": "9ed244ba3453a0c1", "12": "8d1af962d46ec19f", "13": "7e3b558a587a4ebe", "14": "2681c1b3f4f3539e", "15": "8bd61518dd267641", "16": "95add6a975c0cb72", "17": "d5ee72467704e6f0", "18": "fd0841b607871dc7", "19": "0a373ad2197fd1a6", "20": "aecf2fce44ba49c5", "21": "880a74c6d255e5cc", "22": "1c67ad3d97e5c622", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "79d2843a716971c8", "26": "83b0fd3b14363e4d", "27": "eab427ce9a5219e9", "28": "eb3733e409dc7411", "29": "c608f1c6492e1cb1", "30": "f2a40b5f1b29f669", "31": "8f647d3ce08ecd2b", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "23f1d406f6c779ae", "36": "c55f872b3e16ab6f", "37": "3088ae48043ee39d", "38": "c96276581a8c98d4", "39": "932f010dc6115fb4", "40": "444ef0744645f5ac", "41": "386a184c6bd5a40e", "42": "2bfc96d4090afd84", "43": "9a25b1230b5fe649", "44": "8d5f4e992bac9095", "45": "92ab3e5134ed8685", "46": "65718282b3c32109", "47": "01f68dfc34a29d32", "48": "8c471c7baeaaca54", "49": "a54008a71fdd44fa", "50": "bbb2b57d72922b16", "51": "0985ce7473fdd021", "52": "c5a22f1501fe85b7", "53": "287d60115d9acda8", "54": "1331494302f6c136", "55": "f42d242a020b2f05", "56": "2537fe1309d3ab9a", "57": "7862e3ee5a214160", "58": "440ae90e84499b6f", "59": "891f59cda3708718", "60": "a505b7de6257a4e8", "61": "151209871c761759", "62": "d96493a5f110bd4c", "63": "c256b43f75d7809e", "64": "512a2535c88c4284", "66": "e858d75e995c92e5", "71": "cb5ac3401283c378"}
{"0": "796f85041a70fce3", "1": "966174ef01534051", "2": "9cf893b45c314643", "3": "271a5f5154afbdcd", "4": "e8b7c34edb5e6b25", "5": "163ce3e95fc46466", "6": "979dcc63399620ad", "7": "3a3e5d3e70ed45d6", "8": "cf2aba493368e557", "9": "94b2884fbd0d3d50", "10": "d982c7c094e0d01c", "11": "1c4f17c3d154962f", "12": "ab705784bbd1dbdc", "13": "7e3b558a587a4ebe", "14": "a2b13160223b5a98", "15": "5a9014c4a7f87699", "16": "95add6a975c0cb72", "17": "2405e1edb003a83e", "18": "5aa9c1fc3b3c8196", "19": "0a373ad2197fd1a6", "20": "aecf2fce44ba49c5", "21": "8835aeeaa165e9f9", "22": "b683919fcbe30647", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "46e8db3e6e3f37ea", "26": "3ca8c23d3e8220ec", "27": "eab427ce9a5219e9", "28": "536a3a2cb7285674", "29": "c608f1c6492e1cb1", "30": "73c13793fca09f56", "31": "cd6f168abba94fea", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "23f1d406f6c779ae", "36": "92f5f0a14da5908e", "37": "cb8f26249485324a", "38": "29790cf710874dd0", "39": "fdd95375b4a5ddb3", "40": "3dd68cce72af5314", "41": "bf75bfc99d4f9e34", "42": "ffd960136fde00ad", "43": "9a25b1230b5fe649", "44": "852c1bb2446edd9c", "45": "92ab3e5134ed8685", "46": "65718282b3c32109", "47": "188dd5e33354e35d", "48": "8c471c7baeaaca54", "49": "1f976711cda158dc", "50": "bbb2b57d72922b16", "51": "eb6a182204867275", "52": "2ec3c8c088568ba9", "53": "68c45056378341a7", "54": "c58d41e8e580fdc6", "55": "15606ce5d8eec23a", "56": "880a74c6d255e5cc", "57": "f2a40b5f1b29f669", "58": "de5c2bc5e6fe8070", "59": "891f59cda3708718", "60": "a505b7de6257a4e8", "61": "81661714a80b3097", "62": "1366ae24c7e5897d", "63": "c256b43f75d7809e", "64": "86101547c05f96b9", "65": "cb5ac3401283c378", "66": "46204fb2e4d50c53", "67": "98f88c09f1236577", "68": "7ac475ea9bc280f8", "69": "e511846eeba03076", "71": "0b63a2ad1a11ce27", "72": "c84f196a7bd35861", "73": "2b887bf601ccfb9f", "74": "ae2a154311e1f53a", "75": "69fdd23278518884"}
+176 -149
View File
@@ -1,190 +1,193 @@
# Graph Report - juzi (2026-09-28)
# Graph Report - juzi (2026-10-11)
## Corpus Check
- 31 files · ~1,845,638 words
- 59 files · ~4,180,488 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 900 nodes · 2117 edges · 67 communities (46 shown, 21 thin omitted)
- Extraction: 92% EXTRACTED · 8% INFERRED · 0% AMBIGUOUS · INFERRED: 168 edges (avg confidence: 0.52)
- 1133 nodes · 2496 edges · 75 communities (57 shown, 18 thin omitted)
- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 178 edges (avg confidence: 0.53)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `4e3d915b`
- Built from commit: `ee744b6b`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
## Community Hubs (Navigation)
- face-api.js
- n
- t
- app.js
- skin-score.js
- isTensor
- .toBatchTensor
- getEnv
- FaceLandmarks
- disposeUnusedWeightTensors
- n
- normalize
- drawFaceExpressions
- Box
- admin.js
- __awaiter
- extractWeightEntryFactory
- FaceProcessor
- AgeGenderNet
- lib/accounts.js
- server.js
- files
- extractAllFacesAndComputeResults
- .predictAgeAndGender
- .runAndExtendWithFaceDetection
- 巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范
- extractFaces
- 1'me 在线肌肤测试 H5
- head-pose.js
- build_fixtures.py
- .forwardInput
- disposeUnusedWeightTensors
- .loadFromDisk
- facepp-skinanalyze(旷视皮肤分析专业版调用技能)
- 巨子测肤 · 1'me 语音播报内容设计文档 V1.0
- extractParamsFromWeigthMap$1
- mobile-select.iife.min.js
- wi
- gen_voice.py
- initialize
- i
- face-api.js 本地化依赖(h5/vendor/faceapi/)
- regression.js
- isValidNumber
- ui-20261009/manifest.json
- .toString
- FaceMatcher
- build-fixture.py
- DetectSingleFaceLandmarksTask
- so
- tt
- C
- UI 外发版 10.09 图片资源
- TinyYolov2
- cn
- .computeFaceDescriptor
- SsdMobilenetv1
- dr
- UI交互界面调整
- ComputeAllFaceDescriptorsTask
- .draw
- export_psd_assets.py
- FaceLandmark68Net
- rescaleAndNormalize
- start-local.sh
- PredictAllAgeAndGenderWithFaceAlignmentTask
- PredictAllFaceExpressionsWithFaceAlignmentTask
- PredictSingleAgeAndGenderWithFaceAlignmentTask
- k
- PredictSingleFaceExpressionsWithFaceAlignmentTask
- Yo
- mobile-select/README.md
- call_skinanalyze_3view.sh
- TinyXception
- Vc
- FaceDetection
- ff
- ge
- sa
- po
- 护理建议(全量文本,按需求摘抄)
- UI 对齐 10.09 设计稿:调研与实施计划
- FaceLandmarks68
- .forwardInput
- regression.js
- .dispose
- call_skinanalyze.sh
- .extractWeights
- NeuralNetwork
- 提交前 Review(2026-10-11)
- e2e-browser.mjs
- AgeGenderNet
- FaceExpressionNet
- account-client.js
- PredictSingleFaceExpressionsTask
- .runAndExtendWithFaceDetections
- ui-20261009.mjs
- ComputeSingleFaceDescriptorTask
- misans/README.md
- extractFaceTensors
- build_report_copy.py
## God Nodes (most connected - your core abstractions)
1. `__awaiter()` - 59 edges
2. `__generator()` - 59 edges
3. `n()` - 36 edges
4. `t()` - 33 edges
5. `i()` - 33 edges
6. `r()` - 32 edges
3. `n()` - 37 edges
4. `r()` - 35 edges
5. `t()` - 33 edges
6. `i()` - 33 edges
7. `C()` - 32 edges
8. `toNetInput()` - 27 edges
9. `e()` - 22 edges
10. `f()` - 20 edges
## Surprising Connections (you probably didn't know these)
- `loadRecords()` --indirect_call--> `it()` [INFERRED]
h5/js/admin.js → h5/vendor/faceapi/face-api.js
- `bind()` --indirect_call--> `a()` [INFERRED]
h5/js/admin.js → h5/vendor/faceapi/face-api.js
- `detectFrame()` --indirect_call--> `d()` [INFERRED]
h5/js/app.js → h5/vendor/faceapi/face-api.js
- `vizCompose()` --indirect_call--> `h()` [INFERRED]
h5/js/app.js → h5/vendor/faceapi/face-api.js
- `vizCompose()` --indirect_call--> `rh()` [INFERRED]
h5/js/app.js → h5/vendor/faceapi/face-api.js
- `vizCompose()` --indirect_call--> `w()` [INFERRED]
h5/js/app.js → h5/vendor/faceapi/face-api.js
- `renderReport()` --indirect_call--> `t()` [INFERRED]
h5/js/app.js → h5/vendor/faceapi/face-api.js
## Import Cycles
- None detected.
## Communities (67 total, 21 thin omitted)
## Communities (75 total, 18 thin omitted)
### Community 0 - "face-api.js"
Cohesion: 0.02
Nodes (38): bn(), ca(), cd(), ce(), dn(), ee(), er(), et() (+30 more)
Nodes (32): cn(), computeReshapedDimensions(), createBrowserEnv(), createFileSystem(), createNodejsEnv(), dr(), en(), extractBoundingBoxes() (+24 more)
### Community 1 - "n"
Cohesion: 0.07
Nodes (85): a(), ae(), ao(), b(), ba(), be(), bf(), bi() (+77 more)
### Community 1 - "t"
Cohesion: 0.08
Nodes (33): be(), bi(), Bo(), ce(), de(), e(), Ef(), er() (+25 more)
### Community 2 - "app.js"
Cohesion: 0.06
Nodes (71): afterCurrent(), applyMirror(), armNudge(), beginCountdown(), beginDetect(), bindBackdropClose(), busyWithFlow(), cancelCountdown() (+63 more)
Nodes (74): applyMirror(), armNudge(), beginDetect(), bindBackdropClose(), busyWithFlow(), captureFromVideo(), checkStill(), closeOverlay() (+66 more)
### Community 3 - "skin-score.js"
Cohesion: 0.12
Nodes (44): acneGrade(), buildViewModel(), calcAcne(), calcContour(), calcSens(), calcSmooth(), calcTone(), calcWrinkles() (+36 more)
### Community 4 - "isTensor"
Cohesion: 0.33
Nodes (5): extractorsFactory$3(), extractParamsFromWeigthMap$4(), isTensor(), isTensor1D(), isTensor2D()
### Community 4 - "n"
Cohesion: 0.17
Nodes (32): a(), ae(), bf(), cf(), d(), drawContour(), dt(), ea() (+24 more)
### Community 5 - ".toBatchTensor"
Cohesion: 0.08
Nodes (30): conv(), conv$1(), convDown(), convLayer(), convLayer$1(), convNoRelu(), convWithBatchNorm(), denseBlock3() (+22 more)
### Community 6 - "getEnv"
### Community 5 - "normalize"
Cohesion: 0.09
Nodes (26): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), DetectAllFacesTask(), DrawBox(), drawDetections(), drawFaceExpressions() (+18 more)
Nodes (26): conv(), conv$1(), convDown(), convLayer(), convLayer$1(), convNoRelu(), convWithBatchNorm(), denseBlock3() (+18 more)
### Community 7 - "FaceLandmarks"
Cohesion: 0.06
Nodes (16): bgrToRgbTensor(), extendWithFaceLandmarks(), FaceLandmark68NetBase(), FaceLandmarks(), FaceLandmarks5(), FaceLandmarks68(), getCenterPoint(), isDimensions() (+8 more)
### Community 8 - "disposeUnusedWeightTensors"
### Community 6 - "drawFaceExpressions"
Cohesion: 0.22
Nodes (6): disposeUnusedWeightTensors(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$6(), extractParamsFromWeigthMap$7(), extractParamsFromWeigthMapTiny()
Nodes (6): DrawBox(), drawDetections(), drawFaceExpressions(), DrawFaceLandmarks(), FaceExpressions(), isWithFaceExpressions()
### Community 7 - "Box"
Cohesion: 0.13
Nodes (6): Box(), DetectAllFaceLandmarksTask(), extendWithFaceLandmarks(), FaceLandmarks(), minBbox(), ObjectDetection()
### Community 8 - "admin.js"
Cohesion: 0.25
Nodes (23): api(), bind(), closeDetail(), collectFilters(), dimsHtml(), doRetry(), dSec(), el() (+15 more)
### Community 9 - "__awaiter"
Cohesion: 0.22
Nodes (8): __awaiter(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow(), __generator(), Mtcnn(), toNetInput()
Cohesion: 0.14
Nodes (12): __awaiter(), extendWithFaceDescriptor(), extractSingleFaceAndComputeResult(), FaceRecognitionNet(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow() (+4 more)
### Community 10 - "extractWeightEntryFactory"
Cohesion: 0.53
Nodes (6): extractorsFactory$7(), extractWeightEntryFactory(), loadConvParamsFactory(), loadParamsFactory(), loadParamsFactory$1(), loadSeparableConvParamsFactory()
### Community 10 - "AgeGenderNet"
Cohesion: 0.10
Nodes (6): AgeGenderNet(), extractParams$1(), FaceExpressionNet(), FaceLandmark68NetBase(), FaceLandmark68TinyNet(), FaceProcessor()
### Community 11 - "FaceProcessor"
Cohesion: 0.24
Nodes (3): extractParams$1(), FaceLandmark68TinyNet(), FaceProcessor()
### Community 11 - "lib/accounts.js"
Cohesion: 0.07
Nodes (40): build(), count(), fill(), numeric(), atomic(), body(), cookie(), cookies() (+32 more)
### Community 12 - "server.js"
Cohesion: 0.14
Nodes (16): callFacepp(), CRED, DATA_DIR, ERR_MSG, fs, handleAnalyze(), http, isUsableB64() (+8 more)
Cohesion: 0.08
Nodes (48): accounts, appendRecord(), callFacepp(), CRED, csvCell(), DATA_DIR, dumpRaw(), ERR_MSG (+40 more)
### Community 13 - "files"
Cohesion: 0.12
Nodes (15): files, analyze-fail, analyzing, countdown-321, hint-far, hint-front, hint-hold, hint-near (+7 more)
### Community 14 - "extractAllFacesAndComputeResults"
Cohesion: 0.15
Nodes (8): extendWithAge(), extendWithFaceExpressions(), extendWithGender(), extractAllFacesAndComputeResults(), extractSingleFaceAndComputeResult(), PredictAllAgeAndGenderTask(), PredictAllFaceExpressionsTask(), PredictSingleAgeAndGenderTask()
### Community 14 - ".predictAgeAndGender"
Cohesion: 0.28
Nodes (4): extendWithAge(), extendWithGender(), PredictAllAgeAndGenderTask(), PredictSingleAgeAndGenderTask()
### Community 15 - ".runAndExtendWithFaceDetection"
Cohesion: 0.23
Nodes (6): allFacesMtcnn(), allFacesSsdMobilenetv1(), allFacesTinyYolov2(), DetectAllFaceLandmarksTask(), detectAllFaces(), DetectSingleFaceTask()
Cohesion: 0.33
Nodes (5): allFacesMtcnn(), allFacesSsdMobilenetv1(), allFacesTinyYolov2(), detectAllFaces(), DetectSingleFaceTask()
### 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.22
Nodes (6): Box(), extractFaces(), extractFaceTensors(), imageTensorToCanvas(), isTensor3D(), isTensor4D()
Cohesion: 0.19
Nodes (19): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), extractFaces(), extractImagePatches(), getContext2dOrThrow(), getEnv() (+11 more)
### Community 18 - "1'me 在线肌肤测试 H5"
Cohesion: 0.18
Nodes (10): 1'me 在线肌肤测试 H5, Windows 本机部署(提测用), 密钥配置, 已知占位清单, 技术说明, 拍照交互(引导式自动三连拍), 本地运行, 检测流程与评分渲染 (+2 more)
Cohesion: 0.07
Nodes (27): 10.09 新版 H5 实施与验收, 按确认项实现, 文档未定义部分的实施口径, 素材再生成, 验证命令, 公网服务器配置, 公网真机验收清单, 反向代理与后台保护 (+19 more)
### Community 19 - "head-pose.js"
Cohesion: 0.33
@@ -194,13 +197,13 @@ Nodes (8): assertPoints(), check(), clamp(), dist(), estimate(), makeFrontal(),
Cohesion: 0.40
Nodes (9): build_case1(), build_case2(), build_truth(), col(), dump(), main(), parse_value(), set_path() (+1 more)
### Community 21 - ".forwardInput"
Cohesion: 0.22
Nodes (9): boxPredictionLayer(), decodeBoxesLayer(), depthwiseConvLayer(), getCenterCoordinatesAndSizesLayer(), getStridesForLayerIdx(), mobileNetV1(), outputLayer(), pointwiseConvLayer() (+1 more)
### Community 21 - "disposeUnusedWeightTensors"
Cohesion: 0.09
Nodes (24): disposeUnusedWeightTensors(), extractorsFactory$3(), extractorsFactory$5(), extractorsFactory$7(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$1(), extractParamsFromWeigthMap$2() (+16 more)
### Community 22 - ".loadFromDisk"
Cohesion: 0.19
Nodes (5): ComposableTask(), getModelUris(), Gf(), loadWeightMap(), TinyFaceDetector()
Cohesion: 0.25
Nodes (3): ComposableTask(), getModelUris(), TinyFaceDetector()
### Community 23 - "facepp-skinanalyze(旷视皮肤分析专业版调用技能)"
Cohesion: 0.20
@@ -210,101 +213,125 @@ Nodes (9): 1. 凭据(统一管理), 2. 标准调用模板(全可选参数
Cohesion: 0.22
Nodes (8): 1. 音频格式约定(已定), 2. 播报清单(14 条), 3. 播放策略(前端已实现侧约定), 4. 生成验收, A. 步骤引导(进入每个拍照步骤时播,与屏幕步骤文案一致), B. 姿态提示(实时检测不通过时播,同一提示 4 秒内不重复), C. 拍摄与流程, 巨子测肤 · 1'me 语音播报内容设计文档 V1.0
### Community 25 - "extractParamsFromWeigthMap$1"
Cohesion: 0.40
Nodes (3): extractParamsFromWeigthMap$1(), extractParamsFromWeigthMap$3(), seperateWeightMaps()
### Community 25 - "mobile-select.iife.min.js"
Cohesion: 0.20
Nodes (16): _arrayLikeToArray(), _arrayWithHoles(), _arrayWithoutHoles(), _classCallCheck(), _createClass(), _defineProperties(), h(), _iterableToArray() (+8 more)
### Community 26 - "wi"
Cohesion: 0.28
Nodes (9): Ci(), Ei(), Fi(), Ii(), ki(), pe(), ri(), wi() (+1 more)
Cohesion: 0.32
Nodes (8): Ci(), Ei(), Fi(), Ii(), ki(), ri(), wi(), Xt()
### 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 - "initialize"
Cohesion: 0.29
Nodes (7): createBrowserEnv(), createFileSystem(), createNodejsEnv(), initialize(), isBrowser(), monkeyPatch(), setEnv()
### Community 28 - "i"
Cohesion: 0.08
Nodes (32): ba(), bn(), ca(), cl(), da(), dn(), ee(), et() (+24 more)
### Community 29 - "face-api.js 本地化依赖(h5/vendor/faceapi/)"
Cohesion: 0.29
Nodes (6): face-api.js 本地化依赖(h5/vendor/faceapi/), 为什么本地化, 文件清单与体积, 来源与版本, 用法, 许可证
### Community 30 - "regression.js"
Cohesion: 0.60
Nodes (5): diffCtx(), loadJSON(), main(), okNum(), okStr()
### Community 30 - "ui-20261009/manifest.json"
Cohesion: 0.33
Nodes (5): assets, document_size, layers, pages, source
### Community 31 - "isValidNumber"
Cohesion: 0.50
Nodes (4): Dimensions(), isValidNumber(), isValidProbablitiy(), isWithGender()
### Community 31 - ".toString"
Cohesion: 0.33
Nodes (5): FaceMatch(), la(), pr(), pt(), vt()
### Community 33 - "build-fixture.py"
Cohesion: 0.60
Nodes (4): main(), 递归缩放 result 内全部坐标:{left,top,width,height} 矩形与 {x,y} 点,与原数据同为整数。, scale_coords(), to_data_url()
### Community 36 - "so"
Cohesion: 0.50
Nodes (4): Do(), io(), so(), To()
### Community 36 - "C"
Cohesion: 0.08
Nodes (29): ao(), C(), cd(), co(), Do(), eo(), fo(), Ft() (+21 more)
### Community 37 - "tt"
Cohesion: 0.50
Nodes (4): kn(), tt(), wo(), z()
### Community 39 - "cn"
Cohesion: 0.67
Nodes (3): cn(), en(), yn()
### Community 40 - ".computeFaceDescriptor"
Cohesion: 0.18
Nodes (4): ComputeAllFaceDescriptorsTask(), ComputeSingleFaceDescriptorTask(), extendWithFaceDescriptor(), FaceRecognitionNet()
### Community 41 - "SsdMobilenetv1"
### Community 37 - "UI 外发版 10.09 图片资源"
Cohesion: 0.40
Nodes (3): extractorsFactory$5(), extractParamsFromWeigthMap$5(), SsdMobilenetv1()
Nodes (4): UI 外发版 10.09 图片资源, 前端素材对应, 文件位置, 重新导出
### Community 42 - "dr"
Cohesion: 0.67
Nodes (3): dr(), na(), ta()
### Community 39 - "UI交互界面调整"
Cohesion: 0.40
Nodes (4): 1meAI测肤旷视UI问题反馈, UI交互界面调整, 交互, **设计**
### Community 44 - "rescaleAndNormalize"
Cohesion: 0.67
Nodes (3): getSizesForScale(), normalize$1(), rescaleAndNormalize()
### Community 42 - "export_psd_assets.py"
Cohesion: 0.70
Nodes (4): bounds(), layer_at(), main(), save_image()
### Community 49 - "Yo"
Cohesion: 0.67
Nodes (3): qo(), Xo(), Yo()
### Community 44 - "start-local.sh"
Cohesion: 0.50
Nodes (3): HOST, PORT, start-local.sh script
### Community 47 - "k"
Cohesion: 0.18
Nodes (11): b(), gn(), k(), kn(), ne(), tt(), wo(), Yt() (+3 more)
### Community 53 - "护理建议(全量文本,按需求摘抄)"
Cohesion: 0.10
Nodes (19): 5\.1 轮廓(紧塑力), 5\.2 皱纹(紧塑力), 5\.3 肤色(透亮感), 5\.4 平滑度(透亮感), 5\.5 水分(透亮感), 5\.6 泛红(稳韧力), 5\.7 痘痘(稳韧力), 6\.1 轮廓 (+11 more)
### Community 54 - "UI 对齐 10.09 设计稿:调研与实施计划"
Cohesion: 0.11
Nodes (17): 1. 结论和依据, 2. 统一比较口径, 3. 逐页差异和调整内容, 4. 报告数据如何接到新 UI, 5. 登录与“我的报告”的真实能力缺口, 6. 原稿中需要整理的内容, 7. 实施顺序与交付物, 8. 验收定义 (+9 more)
### Community 55 - "FaceLandmarks68"
Cohesion: 0.19
Nodes (3): FaceLandmarks5(), FaceLandmarks68(), getCenterPoint()
### Community 56 - ".forwardInput"
Cohesion: 0.22
Nodes (9): boxPredictionLayer(), decodeBoxesLayer(), depthwiseConvLayer(), getCenterCoordinatesAndSizesLayer(), getStridesForLayerIdx(), mobileNetV1(), outputLayer(), pointwiseConvLayer() (+1 more)
### Community 57 - "regression.js"
Cohesion: 0.60
Nodes (5): diffCtx(), loadJSON(), main(), okNum(), okStr()
### Community 58 - ".dispose"
Cohesion: 0.14
Nodes (13): computeReshapedDimensions(), extractBoundingBoxes(), iou(), isEven(), nonMaxSuppression(), nonMaxSuppression$1(), pyramidDown(), scale() (+5 more)
Cohesion: 0.15
Nodes (12): getSizesForScale(), iou(), nonMaxSuppression(), nonMaxSuppression$1(), normalize$1(), rescaleAndNormalize(), scale(), SsdMobilenetv1() (+4 more)
### Community 61 - ".extractWeights"
Cohesion: 0.08
Nodes (25): createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), extractConvParamsFactory(), extractFCParamsFactory() (+17 more)
### Community 61 - "NeuralNetwork"
Cohesion: 0.05
Nodes (32): bgrToRgbTensor(), createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), Dimensions() (+24 more)
### Community 62 - "提交前 Review(2026-10-11)"
Cohesion: 0.40
Nodes (4): 仍需公网/业务确认, 已发现并修复, 提交前 Review(2026-10-11), 验证
### Community 63 - "e2e-browser.mjs"
Cohesion: 0.29
Nodes (4): EXPECTED, fails, pageErrors, pwRoot
### Community 64 - "account-client.js"
Cohesion: 0.90
Nodes (4): browser(), init(), read(), request()
### Community 71 - "extractFaceTensors"
Cohesion: 0.18
Nodes (9): extendWithFaceDetection(), extendWithFaceExpressions(), extractAllFacesAndComputeResults(), extractFaceTensors(), isTensor3D(), isWithFaceDetection(), isWithFaceLandmarks(), PredictAllFaceExpressionsTask() (+1 more)
## Knowledge Gaps
- **63 isolated node(s):** `step1-front`, `step2-rightface`, `step3-leftface`, `hint-noface`, `hint-near` (+58 more)
- **152 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+147 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **21 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **18 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 `val()` connect `skin-score.js` to `extractFaces`?**
_High betweenness centrality (0.083) - this node is a cross-community bridge._
- **Why does `vizCompose()` connect `app.js` to `n`?**
- **Why does `k()` connect `k` to `face-api.js`, `t`, `app.js`, `n`, `lib/accounts.js`, `i`?**
_High betweenness centrality (0.078) - this node is a cross-community bridge._
- **Why does `renderReport()` connect `app.js` to `t`, `k`?**
_High betweenness centrality (0.058) - this node is a cross-community bridge._
- **Why does `Box()` connect `extractFaces` to `face-api.js`, `.dispose`, `isValidNumber`, `FaceLandmarks`?**
_High betweenness centrality (0.058) - this node is a cross-community bridge._
- **Are the 23 inferred relationships involving `n()` (e.g. with `ae()` and `be()`) actually correct?**
_`n()` has 23 INFERRED edges - model-reasoned connections that need verification._
- **Why does `rate()` connect `lib/accounts.js` to `k`?**
_High betweenness centrality (0.055) - this node is a cross-community bridge._
- **Are the 24 inferred relationships involving `n()` (e.g. with `newRecordId()` and `ae()`) actually correct?**
_`n()` has 24 INFERRED edges - model-reasoned connections that need verification._
- **Are the 27 inferred relationships involving `r()` (e.g. with `handleExport()` and `handleRecordsQuery()`) actually correct?**
_`r()` has 27 INFERRED edges - model-reasoned connections that need verification._
- **Are the 7 inferred relationships involving `t()` (e.g. with `renderReport()` and `e()`) actually correct?**
_`t()` has 7 INFERRED edges - model-reasoned connections that need verification._
- **Are the 9 inferred relationships involving `i()` (e.g. with `da()` and `f()`) actually correct?**
_`i()` has 9 INFERRED edges - model-reasoned connections that need verification._
- **What connects `step1-front`, `step2-rightface`, `step3-leftface` to the rest of the system?**
_63 weakly-connected nodes found - possible documentation gaps or missing edges._
- **What connects `source`, `document_size`, `pages` to the rest of the system?**
_152 weakly-connected nodes found - possible documentation gaps or missing edges._
File diff suppressed because one or more lines are too long
+8502 -1480
View File
File diff suppressed because it is too large Load Diff
+744 -14
View File
@@ -40,23 +40,23 @@
"semantic_hash": ""
},
"h5/js/app.js": {
"mtime": 1790531707.8223634,
"ast_hash": "7c3652449c905d9f19ca37a66089766f",
"mtime": 1791646682.4027648,
"ast_hash": "b838a3efa4351bb87d5f17644bf83ca7",
"semantic_hash": ""
},
"h5/js/head-pose.js": {
"mtime": 1790528422.8265557,
"ast_hash": "165cc2ae73d0a9526db0755ec62ffaac",
"mtime": 1791559485.790093,
"ast_hash": "cdfc5962793a4d6e567ffe00be7653e8",
"semantic_hash": ""
},
"h5/js/skin-score.js": {
"mtime": 1790528158.6665542,
"ast_hash": "61d27784c13fc9fd5ea3b4e2f6187756",
"mtime": 1791645379.1321833,
"ast_hash": "12fe3e0e5fd4cbe7f0a79a7da01c380b",
"semantic_hash": ""
},
"h5/server.js": {
"mtime": 1790528158.6705542,
"ast_hash": "e23a541e2ce85e0815616071820b46ef",
"mtime": 1791710640.6026413,
"ast_hash": "a63e26c0f78becff09cc50e427cb0054",
"semantic_hash": ""
},
"h5/test/build_fixtures.py": {
@@ -135,13 +135,13 @@
"semantic_hash": ""
},
"h5/README.md": {
"mtime": 1790531597.4743752,
"ast_hash": "26db3c846af2efc0a4bfb442985e2922",
"mtime": 1791646538.376033,
"ast_hash": "1f8bb2cad20e467a93e1120dc7cf3924",
"semantic_hash": ""
},
"h5/index.html": {
"mtime": 1790531666.4743714,
"ast_hash": "66cb0b0c306fcc9adb4dbed358651d13",
"mtime": 1791646269.975195,
"ast_hash": "c2661595e503e2f166f1be390696ce0c",
"semantic_hash": ""
},
"h5/vendor/faceapi/README.md": {
@@ -770,8 +770,8 @@
"semantic_hash": ""
},
"h5/test/e2e-browser.mjs": {
"mtime": 1790531366.4343376,
"ast_hash": "3ae597baedac698f02f27c5662784348",
"mtime": 1791646391.2915454,
"ast_hash": "dc47c78ddf5de136d59d73fb19d8da81",
"semantic_hash": ""
},
"h5/assets/svg/prod-badge.svg": {
@@ -808,5 +808,735 @@
"mtime": 1790528422.8225558,
"ast_hash": "9f7ec9320aad81e86fbb1677228e6483",
"semantic_hash": ""
},
"design/ui-20261009/manifest.json": {
"mtime": 1791642120.005687,
"ast_hash": "30a5ef4a5abcd6c6c4294e8202a4bad4",
"semantic_hash": ""
},
"h5/js/admin.js": {
"mtime": 1791556943.863973,
"ast_hash": "573a1a971cc3d00a16c8b9d53529f243",
"semantic_hash": ""
},
"h5/js/region-data.js": {
"mtime": 1791559485.790093,
"ast_hash": "9ede70cb3ed9777a62559451e1969b9d",
"semantic_hash": ""
},
"h5/start-local.sh": {
"mtime": 1791559485.790093,
"ast_hash": "f71b1c8e2ada83f6ee607ae4577d0b9a",
"semantic_hash": ""
},
"h5/vendor/mobile-select/mobile-select.iife.min.js": {
"mtime": 1791559485.790093,
"ast_hash": "52578c3b95933f96493d3b879d353421",
"semantic_hash": ""
},
"tools/export_psd_assets.py": {
"mtime": 1791642102.9273047,
"ast_hash": "7cee68c3db2cd4a52b58b8e380e2fe8d",
"semantic_hash": ""
},
"MP_verify_kpx234XimQGtFPo6.txt": {
"mtime": 1791639433.9595106,
"ast_hash": "3acc5e996d0ddc5b2b225b56536d2bf3",
"semantic_hash": ""
},
"design/ui-20261009/README.md": {
"mtime": 1791710791.707398,
"ast_hash": "097628df23775e8d518f9ec83593e211",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988.md": {
"mtime": 1791556943.7718663,
"ast_hash": "d99151ccfc4d73a421f49546feef45fa",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u7b2c\u4e8c\u8f6e2\u53cd\u9988.md": {
"mtime": 1791639433.9595106,
"ast_hash": "7c20a160d9b965ff019445cae51c5628",
"semantic_hash": ""
},
"h5/admin.html": {
"mtime": 1791556943.863973,
"ast_hash": "8dad311cd83b0ec640bcf71ddb9a255c",
"semantic_hash": ""
},
"h5/vendor/mobile-select/README.md": {
"mtime": 1791559485.790093,
"ast_hash": "fe3287899b96f598c60f9bc030a1368e",
"semantic_hash": ""
},
"design/ui-20261009/assets-overview.jpg": {
"mtime": 1791642120.005687,
"ast_hash": "d9475b775e202ae0e0e329b48625529f",
"semantic_hash": ""
},
"design/ui-20261009/pages-overview.jpg": {
"mtime": 1791642119.9744806,
"ast_hash": "1231c4badaf76d859d02c71beb67b5d3",
"semantic_hash": ""
},
"design/ui-20261009/pages/01-\u542f\u52a8\u9875.png": {
"mtime": 1791641925.2282495,
"ast_hash": "9e0086ed5831752589a87e5a4bf41a32",
"semantic_hash": ""
},
"design/ui-20261009/pages/02-\u542f\u52a8\u9875\u5f39\u7a97.png": {
"mtime": 1791641927.5536723,
"ast_hash": "b69f8d3b109472bcffb08dc861bae7ec",
"semantic_hash": ""
},
"design/ui-20261009/pages/03-\u6211\u7684\u62a5\u544a.png": {
"mtime": 1791641931.276532,
"ast_hash": "28b96724cba921c1b996bccf5921fcc4",
"semantic_hash": ""
},
"design/ui-20261009/pages/04-\u6863\u6848\u586b\u5199.png": {
"mtime": 1791641935.9516084,
"ast_hash": "7c702fa5005b0009998da437678d643a",
"semantic_hash": ""
},
"design/ui-20261009/pages/05-\u62cd\u7167\u5f39\u7a97.png": {
"mtime": 1791641938.6036084,
"ast_hash": "949fecb7cf12227e2afc0223977f0774",
"semantic_hash": ""
},
"design/ui-20261009/pages/06-\u6b63\u9762.png": {
"mtime": 1791641940.6992414,
"ast_hash": "9cc466bf5e1e34852a672570eaf075c4",
"semantic_hash": ""
},
"design/ui-20261009/pages/07-\u5de6\u9762.png": {
"mtime": 1791641942.8299313,
"ast_hash": "09f1a2059586cd430e79f21d2abe262f",
"semantic_hash": ""
},
"design/ui-20261009/pages/08-\u53f3\u9762.png": {
"mtime": 1791641945.0379312,
"ast_hash": "1394a72d8fdeb223d2ccab4c7121f542",
"semantic_hash": ""
},
"design/ui-20261009/pages/09-\u62a5\u544a\u9875.png": {
"mtime": 1791641991.6536736,
"ast_hash": "7593a81623b7f56aec5272bf3435132b",
"semantic_hash": ""
},
"design/ui-20261009/pages/10-\u767b\u5f55.png": {
"mtime": 1791641995.750234,
"ast_hash": "193866f312d2652e3bfad47b9cffb41c",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 1.png": {
"mtime": 1791556943.775871,
"ast_hash": "26f81b5937eeb366495cb1a8cd6a83a7",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 2.png": {
"mtime": 1791556943.7798755,
"ast_hash": "66c1339d62b9ff4cc7e0437625575650",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 3.png": {
"mtime": 1791556943.7798755,
"ast_hash": "5f3a5fab25af9f28a73681afcd8163b5",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 4.png": {
"mtime": 1791556943.7838802,
"ast_hash": "d6e125783fdd17d64104479ecec6b178",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 5.png": {
"mtime": 1791556943.7918894,
"ast_hash": "9ae5ae786e478c26c2cd6a4cd31e8548",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 6.png": {
"mtime": 1791556943.7918894,
"ast_hash": "26f81b5937eeb366495cb1a8cd6a83a7",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image 7.png": {
"mtime": 1791556943.7998989,
"ast_hash": "ff17d0fb064a446a66c80e16c442d1bc",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/image.png": {
"mtime": 1791556943.7998989,
"ast_hash": "4231c15316cf0172bc8a61e3608e4a8b",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0215v_ae6e553b-8196-4962-9529-abfd20b33d3g.jpg": {
"mtime": 1791556943.7998989,
"ast_hash": "80e37fba538c321c72f1e07b1cc01fdc",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0215v_de81e319-a8c7-4ec8-bd78-ae4a127ef30g.jpg": {
"mtime": 1791556943.7998989,
"ast_hash": "2cd1dd131c8e8e6d644c8261b4c48f55",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_45a139b6-f58c-4bab-8ca1-1c29fcde18fg.png": {
"mtime": 1791556943.8039033,
"ast_hash": "68e53d7530b6fc82219497a9c3a4da67",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_5d95bb41-92ae-4fa4-82a5-74f274e58cbg.png": {
"mtime": 1791556943.8159173,
"ast_hash": "4647889d0de806bce9061e475450ca0e",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_71bbe9b7-3add-49ac-a482-294ab995bf8g.png": {
"mtime": 1791556943.819922,
"ast_hash": "de799cb297b18ad7af5dcbedcb7a3af7",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_9c98146e-8996-4191-b21f-077c525ea5eg 1.png": {
"mtime": 1791556943.8239264,
"ast_hash": "2100794ade2e248b74fb725b40772549",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_9c98146e-8996-4191-b21f-077c525ea5eg.png": {
"mtime": 1791556943.8239264,
"ast_hash": "2100794ade2e248b74fb725b40772549",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_d853ee3b-5310-4c90-b34d-ab43b9acff4g.png": {
"mtime": 1791556943.8239264,
"ast_hash": "4be961746f76e410175b22c6cb4a297e",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_d9062dad-94c8-49ca-8f2a-02525fcf6bbg.png": {
"mtime": 1791556943.8279312,
"ast_hash": "6bd46dfccfa2c9eef496406494c28805",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/img_v3_0216a_df6ae147-0add-4863-879f-38f2dc94220g.png": {
"mtime": 1791556943.8279312,
"ast_hash": "0cee77873e56c1d57caf3c30739e4e77",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u6211\u7684\u62a5\u544a.jpg": {
"mtime": 1791556943.8279312,
"ast_hash": "a5cb508204efbcc0aa814607b5171b9e",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u622a\u5c4f2026-09-28 13.38.51.png": {
"mtime": 1791556943.8359404,
"ast_hash": "3c7b6fe631e0002929548a3c50733f8b",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u622a\u5c4f2026-09-28 13.43.25.png": {
"mtime": 1791556943.839945,
"ast_hash": "f54f57c72a1f3ad50fc3ce20f2f72900",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u622a\u5c4f2026-09-28 13.44.10.png": {
"mtime": 1791556943.8479543,
"ast_hash": "e7208ae3baa0a3e4677176242f089d7f",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u622a\u5c4f2026-09-28 13.45.46.png": {
"mtime": 1791556943.851959,
"ast_hash": "f0590a59b792b30fcbf8e402e12b701c",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u622a\u5c4f2026-09-28 13.56.32.png": {
"mtime": 1791556943.8559637,
"ast_hash": "ca8c8ba2e8ddb457a47cd811a1b1e525",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u622a\u5c4f2026-09-28 14.13.35.png": {
"mtime": 1791556943.8599682,
"ast_hash": "7b90c45f235da04d0bbbb937728e1e1e",
"semantic_hash": ""
},
"feedback/1meAI\u6d4b\u80a4\u65f7\u89c6UI\u95ee\u9898\u53cd\u9988/\u56fe\u7247\u548c\u9644\u4ef6/\u6863\u6848\u586b\u5199.png": {
"mtime": 1791556943.863973,
"ast_hash": "dd7e776e075a90325e826e6af5a3dc06",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-history.jpg": {
"mtime": 1791642110.8726454,
"ast_hash": "b40384ccab84c686ca7e95f06ef402d1",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-login.jpg": {
"mtime": 1791642107.6766243,
"ast_hash": "7d9428b9c02024b7ba0b9e3845c0811e",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-profile.jpg": {
"mtime": 1791642106.283487,
"ast_hash": "7d9428b9c02024b7ba0b9e3845c0811e",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-report.jpg": {
"mtime": 1791642109.7565744,
"ast_hash": "7d72639b3df259555a0db509555c6e92",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-splash.jpg": {
"mtime": 1791642105.7254517,
"ast_hash": "4d1ef1156513a372f62383d15a0542f0",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/brand-login.png": {
"mtime": 1791642110.9038641,
"ast_hash": "b4a8630878423bd42c9a2ab0178637b3",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/brand-logo.png": {
"mtime": 1791642110.892157,
"ast_hash": "6d3045d44d9fc90850216c6e1291837f",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/camera-mask-front.png": {
"mtime": 1791642116.7875311,
"ast_hash": "de2962a8f6f9851c7076c6e0935a225a",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/camera-mask-left.png": {
"mtime": 1791642117.4116583,
"ast_hash": "0192103bb8e372166a6cd271e8eae9a2",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/camera-mask-right.png": {
"mtime": 1791642117.0878923,
"ast_hash": "40b770583c47ba0f539661cb9a466eee",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-album.png": {
"mtime": 1791642110.9116688,
"ast_hash": "2d819e63db048d874cbc429d3131037d",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-back.png": {
"mtime": 1791642110.9077663,
"ast_hash": "410c4d4e6d363644e9e073fd1cdf5391",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-close.png": {
"mtime": 1791642110.9077663,
"ast_hash": "6dd0c1f1555d55f54ec80b8231089e4d",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-dropdown.png": {
"mtime": 1791642110.9077663,
"ast_hash": "20cb370372a6a3796274703c83a2790a",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-guest.png": {
"mtime": 1791642110.9194734,
"ast_hash": "3f04d7abdf607cfc4c1a737e00a18ba3",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-shutter.png": {
"mtime": 1791642110.935083,
"ast_hash": "6cb6892af9f6ad8828bc65d01fa42a36",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-switch-camera.png": {
"mtime": 1791642110.915571,
"ast_hash": "6197c8000c21156ffecdf77f9c5ed5ba",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/icon-wechat.png": {
"mtime": 1791642110.9194734,
"ast_hash": "42dd3e96cdd78ae90796627321fa9287",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/product-25.png": {
"mtime": 1791642111.5399463,
"ast_hash": "5380d9e7b154bc65e44bfd9816453abe",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/product-35.png": {
"mtime": 1791642112.0158572,
"ast_hash": "06b3d30cfa18f2d0412d5bd0b52d4281",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/product-50.png": {
"mtime": 1791642112.2265003,
"ast_hash": "6c7721402acb3de9a77b89a58bba8e72",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/product-badge.png": {
"mtime": 1791642112.2343018,
"ast_hash": "f345c695ccfa68eda6954f0e9c372566",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/sample-contour.png": {
"mtime": 1791642113.7790165,
"ast_hash": "564023f6104798a65ba176cd0d39fe68",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/sample-lines.png": {
"mtime": 1791642113.8102229,
"ast_hash": "620741bd7da835b9a7e7236bda0eca04",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/sample-redness.png": {
"mtime": 1791642116.4364598,
"ast_hash": "564023f6104798a65ba176cd0d39fe68",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/sample-tone.png": {
"mtime": 1791642114.0988817,
"ast_hash": "aed72b95748480cce62f6a2fb7ed7c24",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/score-ring-base.png": {
"mtime": 1791642112.2616074,
"ast_hash": "4286d187e29909a97aaa178c09fdce30",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/score-ring-value.png": {
"mtime": 1791642112.285012,
"ast_hash": "7677768b6dcc6531a73506f65b21548f",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/skin-0-dry.png": {
"mtime": 1791642110.9780085,
"ast_hash": "9c9ca68325293fd44605c9b03d658306",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/skin-1-mixeddry.png": {
"mtime": 1791642111.0248368,
"ast_hash": "1c282221809cda40e6b74fd98181bdfa",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/skin-2-neutral.png": {
"mtime": 1791642111.0677626,
"ast_hash": "5090258c61d6c52c6e16f77fe91fb86a",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/skin-3-oily.png": {
"mtime": 1791642111.1106884,
"ast_hash": "9ffc7732de8c04507e8917a771f92c91",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/skin-4-mixedoily.png": {
"mtime": 1791642111.153614,
"ast_hash": "e76e01938d93d1a662d01e4713b54c94",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/evidence.json": {
"mtime": 1791642461.0152285,
"ast_hash": "1ea9200cc1dce15c6586edd965ddc0b4",
"semantic_hash": ""
},
"h5/js/account-client.js": {
"mtime": 1791646011.3632386,
"ast_hash": "1aad127f864693ee873d59b177386b33",
"semantic_hash": ""
},
"h5/js/camera-geometry.js": {
"mtime": 1791646239.2012978,
"ast_hash": "08048bc5e491ca47275afe067bedbc1c",
"semantic_hash": ""
},
"h5/js/report-copy.js": {
"mtime": 1791645357.4367466,
"ast_hash": "86f574571b8e882868fce221677cf097",
"semantic_hash": ""
},
"h5/js/report-ui.js": {
"mtime": 1791646198.024173,
"ast_hash": "5cb7f2ac736b6859ed580f5c934b1061",
"semantic_hash": ""
},
"h5/lib/accounts.js": {
"mtime": 1791710640.6026413,
"ast_hash": "e36024ccb6c9d6a2d2a0187942d5c65b",
"semantic_hash": ""
},
"h5/test/accounts.js": {
"mtime": 1791710640.6026413,
"ast_hash": "f036faf880172eb33e3d0fd4e5c462f7",
"semantic_hash": ""
},
"h5/test/report-persistence.mjs": {
"mtime": 1791710640.6026413,
"ast_hash": "92699686424262cfe208355ce040f236",
"semantic_hash": ""
},
"h5/test/ui-20261009.mjs": {
"mtime": 1791646682.4027648,
"ast_hash": "c2754fb520f28a48391662a49860687c",
"semantic_hash": ""
},
"tools/build_report_copy.py": {
"mtime": 1791645357.4060252,
"ast_hash": "e4d2c1e2ab552c08cb271f0ec042668b",
"semantic_hash": ""
},
"tools/prepare_h5_assets.py": {
"mtime": 1791646238.76662,
"ast_hash": "6567fff1561b8cc43ae956b97adffb7e",
"semantic_hash": ""
},
"docs/10.09\u65b0\u7248H5\u5b9e\u65bd\u4e0e\u9a8c\u6536.md": {
"mtime": 1791710850.0228443,
"ast_hash": "e3126d7bce54a235d580778609a46dd3",
"semantic_hash": ""
},
"docs/UI\u5bf9\u9f5010.09\u8bbe\u8ba1\u7a3f-\u8c03\u7814\u4e0e\u5b9e\u65bd\u8ba1\u5212.md": {
"mtime": 1791642695.148235,
"ast_hash": "1061787758ab6ac500ebd8617a211955",
"semantic_hash": ""
},
"docs/\u5fae\u4fe1\u767b\u5f55\u63a5\u5165\u4e0e\u516c\u7f51\u90e8\u7f72\u8bf4\u660e.md": {
"mtime": 1791710640.6026413,
"ast_hash": "70d447aea33b739f438e0c24503c2e49",
"semantic_hash": ""
},
"h5/assets/fonts/misans/README.md": {
"mtime": 1791646269.9287534,
"ast_hash": "9f471a9be8b8ba08e9af70d95f73958b",
"semantic_hash": ""
},
"reference/AI\u6d4b\u80a4\u62a5\u544a\u9875\u8bdd\u672f\u4fee\u6539.md": {
"mtime": 1791644142.8049476,
"ast_hash": "36beb496de948671dd57252803103a9d",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/01-splash.png": {
"mtime": 1791642440.1249583,
"ast_hash": "3da7aac3c729a22044e0bc38a2d0a5e8",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/02-privacy.png": {
"mtime": 1791642440.7098482,
"ast_hash": "b7ad52ea336102a0239497176799243c",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/03-profile.png": {
"mtime": 1791642441.2944968,
"ast_hash": "2ac2495f969b0662fbb0276b9e6f2a80",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/04-guide.png": {
"mtime": 1791642445.54505,
"ast_hash": "4ceb830ca14aa9ee40cc342753012159",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/05-camera-front.png": {
"mtime": 1791642446.0783443,
"ast_hash": "38bce9558d5a92675a34db1921ad02a3",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/06-camera-right.png": {
"mtime": 1791642450.9363437,
"ast_hash": "5b157765b11f784a825058bbf83f0fbc",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/07-camera-left.png": {
"mtime": 1791642454.9502327,
"ast_hash": "a1bad1a71d685011e276bcb11a32bfb5",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/08-report-top.png": {
"mtime": 1791642456.0373278,
"ast_hash": "cc03d71114e67a70be1da597be3a1004",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/09-report-tab-0.png": {
"mtime": 1791642456.5868485,
"ast_hash": "fffafbf39ef5034fd482f7a8913e77a3",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/09-report-tab-1.png": {
"mtime": 1791642457.1358962,
"ast_hash": "a9711819779892e12e4822adea670327",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/09-report-tab-2.png": {
"mtime": 1791642457.6528962,
"ast_hash": "98f3345d71f386432a0abdc4101372c1",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/10-report-full.png": {
"mtime": 1791642457.8252294,
"ast_hash": "75079ede2b0ec48e2a61bf880c3df379",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/comparison-flow.jpg": {
"mtime": 1791642519.1911554,
"ast_hash": "fe2bfa1ccdfa0009a33dea1eb640aa9b",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/comparison-report.jpg": {
"mtime": 1791642519.3780205,
"ast_hash": "c00044e21709055f246aeedaff0e2e1b",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/splash-375x844.png": {
"mtime": 1791642458.8775625,
"ast_hash": "72f3e6d936f46bab4abfc331598c0bc0",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/splash-390x844.png": {
"mtime": 1791642459.9445622,
"ast_hash": "343b642a20aad07ee2998cbe0ff5897b",
"semantic_hash": ""
},
"design/ui-20261009/audit-current/splash-414x844.png": {
"mtime": 1791642461.0152285,
"ast_hash": "a930db67507523cbe3dda1676fd2827e",
"semantic_hash": ""
},
"design/ui-20261009/decisions/01-header.jpg": {
"mtime": 1791643908.9231389,
"ast_hash": "96222db0eafd143c991e3d25ff2b4f83",
"semantic_hash": ""
},
"design/ui-20261009/decisions/02-login.jpg": {
"mtime": 1791643909.0195472,
"ast_hash": "e700914fc28d01fb76f801bbd9bc0b45",
"semantic_hash": ""
},
"design/ui-20261009/decisions/03-history.jpg": {
"mtime": 1791643909.0426853,
"ast_hash": "a3509a51b2487038f4f45e9948286073",
"semantic_hash": ""
},
"design/ui-20261009/decisions/04-score.jpg": {
"mtime": 1791643909.1622317,
"ast_hash": "6794174cba816fd3800f32c1987e6c4c",
"semantic_hash": ""
},
"design/ui-20261009/decisions/05-tabs.jpg": {
"mtime": 1791643909.270209,
"ast_hash": "026049c527dc312bcc569bc3bfd40901",
"semantic_hash": ""
},
"design/ui-20261009/decisions/06-content.jpg": {
"mtime": 1791643909.3781865,
"ast_hash": "ea8f898ddb9edd5ce9f1029078937eb2",
"semantic_hash": ""
},
"design/ui-20261009/decisions/07-products.jpg": {
"mtime": 1791643909.4938765,
"ast_hash": "751604b9f1bbcd77158e7a69e1b46054",
"semantic_hash": ""
},
"design/ui-20261009/decisions/08-camera.jpg": {
"mtime": 1791643909.520871,
"ast_hash": "66e7c9baba319c310828093f6a380646",
"semantic_hash": ""
},
"design/ui-20261009/decisions/09-font.jpg": {
"mtime": 1791643909.6172793,
"ast_hash": "12881243d056472816871ccf0d028b1c",
"semantic_hash": ""
},
"design/ui-20261009/decisions/10-proofreading.jpg": {
"mtime": 1791643909.6674116,
"ast_hash": "927a5d7e5a1460c961a447ac48f184c4",
"semantic_hash": ""
},
"design/ui-20261009/verification/01-login.png": {
"mtime": 1791710678.3993611,
"ast_hash": "546575bd6c19464adfd8033f1416e41f",
"semantic_hash": ""
},
"design/ui-20261009/verification/02-home.png": {
"mtime": 1791710681.0034657,
"ast_hash": "48cb27f9eb1d5f01f3ca00097b31d5b8",
"semantic_hash": ""
},
"design/ui-20261009/verification/03-history-empty.png": {
"mtime": 1791710681.5034268,
"ast_hash": "cf7cc9fdf15a8fe2c2276ffbf01e9356",
"semantic_hash": ""
},
"design/ui-20261009/verification/04-privacy.png": {
"mtime": 1791710682.4802737,
"ast_hash": "349e9841ce4f114a2816c52fea2301c3",
"semantic_hash": ""
},
"design/ui-20261009/verification/05-profile.png": {
"mtime": 1791710683.0148475,
"ast_hash": "2e624c0cb91f96fe84e41878cf9852b5",
"semantic_hash": ""
},
"design/ui-20261009/verification/06-report-top.png": {
"mtime": 1791710685.010846,
"ast_hash": "ad6cbf32ddbb4ef628f8b8bf6f970af9",
"semantic_hash": ""
},
"design/ui-20261009/verification/07-report-full.png": {
"mtime": 1791710685.1146839,
"ast_hash": "8775ce75d26200ab9341f662b8aaf40d",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-history-h5.jpg": {
"mtime": 1791646239.0227692,
"ast_hash": "1dca9bdb3e19bdf837fc317e8dc3d65a",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-login-h5.jpg": {
"mtime": 1791646238.9645536,
"ast_hash": "bbc72a85580326d228e92c0efd0293aa",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-profile-h5.jpg": {
"mtime": 1791646238.9994829,
"ast_hash": "bbc72a85580326d228e92c0efd0293aa",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-report-h5.jpg": {
"mtime": 1791646239.1003904,
"ast_hash": "b49c61b68a714da65fdb706060e1a4f0",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/bg-splash-h5.jpg": {
"mtime": 1791646238.933505,
"ast_hash": "0ab40c14387e86508639e733fea6d168",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/camera-guide-front.png": {
"mtime": 1791642118.1918173,
"ast_hash": "0e487819610ac8aeb58b728f629910df",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/camera-guide-left.png": {
"mtime": 1791642119.9198694,
"ast_hash": "ef6f454709623d7eae301b3d4be52054",
"semantic_hash": ""
},
"h5/assets/img/ui-20261009/camera-guide-right.png": {
"mtime": 1791642119.049992,
"ast_hash": "02af0bb38e2630bcdd00d8349f3c0d44",
"semantic_hash": ""
},
"design/ui-20261009/verification/08-camera-front-layout.png": {
"mtime": 1791710683.453275,
"ast_hash": "b9d04eed0983f1f49fed6c663070ecc1",
"semantic_hash": ""
},
"design/ui-20261009/verification/08-camera-left-layout.png": {
"mtime": 1791710683.5186543,
"ast_hash": "2cb973828c1d18bfbcb5c0cb8ad06d41",
"semantic_hash": ""
},
"design/ui-20261009/verification/08-camera-right-layout.png": {
"mtime": 1791710683.4840417,
"ast_hash": "4b299e86432feb2697dd739dc77a825d",
"semantic_hash": ""
},
"h5/test/wechat-browser.mjs": {
"mtime": 1791710791.703553,
"ast_hash": "7d44f0e7fee4a30c6654db57de57923e",
"semantic_hash": ""
},
"docs/2026-10-11\u63d0\u4ea4\u524dReview.md": {
"mtime": 1791710850.0228443,
"ast_hash": "93bae80d0b6998a1d31616c512261e68",
"semantic_hash": ""
}
}
+6
View File
@@ -121,6 +121,12 @@ node server.js # 默认 8080,可用 PORT=xxx 修改
| `GET /api/admin/stats` | 今日/累计检测量、成功率、平均耗时、失败原因分布、三维度档位分布、产品组别分布、近 14 天每日检测量/成功数 |
| `GET /api/admin/export?from=&to=` | CSV 导出(UTF-8 BOM,Content-Disposition attachment 带日期区间文件名);禁止 raw_json 进单元格(Excel 单格 32767 字符截断) |
## 10.09 更新
新版已增加登录入口、后端账号隔离的最近 5 份完整报告、七项独立检测视图和新版话术/素材。
本机浏览器只缓存随机身份凭据,报告保存在服务器;微信需公网 HTTPS、具备网页授权权限的服务号及相应环境变量。
详见 [新版实施与验收](../docs/10.09新版H5实施与验收.md) 和 [微信登录接入与公网部署说明](../docs/微信登录接入与公网部署说明.md)。下方旧功能说明以这两份更新文档为准。
## 部署
需要 Node ≥ 18 运行 `server.js`(负责静态与 API 中转),**不能用纯静态托管**(密钥不能进前端)。
Binary file not shown.
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
# MiSans 字体
本应用使用 MiSans 字体(小米科技有限责任公司)。
- 官方来源:https://hyperos.mi.com/font/zh/download/
- 下载包:https://hyperos.mi.com/font-download/MiSans.zip
- 下载日期:2026-10-10
- 文件:官方原始 MiSans-Regular.woff2、MiSans-Semibold.woff2,未修改、未子集化。
- 许可协议:上述官方下载页的「许可协议」;此处字体随本应用使用,不作为独立字库产品分发。
页面「我的报告」底部包含字体使用声明。请保持声明,单独再分发或改造字体前需另行确认授权。
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 KiB

Some files were not shown because too many files have changed in this diff Show More