Compare commits

..
1 Commits
Author SHA1 Message Date
xsl 2a7593b736 save 2026-10-10 14:23:43 +08:00
235 changed files with 3784 additions and 36660 deletions
-42
View File
@@ -1,42 +0,0 @@
# 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.

Before

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 KiB

@@ -1,780 +0,0 @@
{
"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.

Before

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

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

Before

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

@@ -1,59 +0,0 @@
{
"description": "Smaller product-card delivery images. Original PSD crops preserved.",
"retained": "Background/scan WebPs are smaller than JPEG; transparent icons/masks remain PNG.",
"assets": [
{
"source": "h5/assets/img/ui-20261012/product-25.webp",
"source_sha256": "c18827342d23bbff2de04c3a2ecbeeae9b16eb96f3a9f7e30f2a66cdc21beddc",
"source_bytes": 276778,
"file": "h5/assets/img/ui-20261012/product-25.jpg",
"sha256": "2c399cd6bd7bd783f698a91b9203a7ba42b92295d58bbeb0b1c2a884e862f00b",
"bytes": 63959,
"size": [
504,
503
],
"quality": 90,
"subsampling": 0,
"progressive": true,
"matte": "#FFFFFF",
"psnr_db": 40.98
},
{
"source": "h5/assets/img/ui-20261012/product-35.webp",
"source_sha256": "c1dc455c8072da17ac06cee386248b358947da65bd190b714f2ccb25360afea4",
"source_bytes": 267094,
"file": "h5/assets/img/ui-20261012/product-35.jpg",
"sha256": "ab4c5623235020b1129f564b733fe843c539088e7b62b2d38ed42a204e4af113",
"bytes": 66077,
"size": [
504,
503
],
"quality": 90,
"subsampling": 0,
"progressive": true,
"matte": "#FFFFFF",
"psnr_db": 41.47
},
{
"source": "h5/assets/img/ui-20261012/product-50.webp",
"source_sha256": "86647c8882caf62c43eafb1efe495bad3289126cab73a88c8963b7ad64ffa084",
"source_bytes": 331924,
"file": "h5/assets/img/ui-20261012/product-50.jpg",
"sha256": "78687985751afbf60c374f2605dee372ac64ffc5271aa54ddca7897443de3047",
"bytes": 153787,
"size": [
504,
503
],
"quality": 96,
"subsampling": 0,
"progressive": true,
"matte": "#FFFFFF",
"psnr_db": 41.94
}
],
"source_bytes": 875796,
"delivery_bytes": 283823
}
-501
View File
@@ -1,501 +0,0 @@
{
"source": "UI外发版10.09.psd",
"source_sha256": "c7698f5900adc7476286818450d928e8fa2ce2e58cda09375ff2b861629fd58f",
"document_size": [
7330,
16411
],
"native_header_px": 248,
"design_scale": 2.88,
"assets": [
{
"file": "h5/assets/img/ui-20261012/splash-slogan.png",
"source_layers": [
"0/5",
"0/4"
],
"bbox": [
1415,
391,
2133,
608
],
"size": [
718,
217
],
"bytes": 12781,
"sha256": "c9dee693eb3c1d566bb08d3770e7dd2f0c22e7d4e0b81bbe5e10ad8219b26044"
},
{
"file": "h5/assets/img/ui-20261012/brand-lockup.png",
"source_layers": [
"0/1"
],
"bbox": [
1515,
1861,
2032,
1920
],
"size": [
517,
59
],
"bytes": 7013,
"sha256": "3cb697d6c5542562a9cea20554b0772f2c0137b9c3977ff258908024d5a8e9ed"
},
{
"file": "h5/assets/img/ui-20261012/button-start-label.png",
"source_layers": [
"0/3/1"
],
"bbox": [
1696,
2005,
1857,
2045
],
"size": [
161,
40
],
"bytes": 2163,
"sha256": "fd88b174f120845d8045a78a36bc7665516d91011f7ea0ebc7fe200271e17738"
},
{
"file": "h5/assets/img/ui-20261012/button-history-label.png",
"source_layers": [
"0/2/2/2"
],
"bbox": [
1696,
2252,
1859,
2291
],
"size": [
163,
39
],
"bytes": 2024,
"sha256": "0253d761f63bda89301c1eec9df84352a2f5dd1aa97884e27ebf91092c0816d8"
},
{
"file": "h5/assets/img/ui-20261012/product-25.webp",
"source_layers": [
"8/1/0"
],
"bbox": [
1765,
14677,
2269,
15180
],
"size": [
504,
503
],
"bytes": 276778,
"sha256": "c18827342d23bbff2de04c3a2ecbeeae9b16eb96f3a9f7e30f2a66cdc21beddc"
},
{
"file": "h5/assets/img/ui-20261012/product-35.webp",
"source_layers": [
"8/1/1"
],
"bbox": [
1765,
15228,
2269,
15731
],
"size": [
504,
503
],
"bytes": 267094,
"sha256": "c1dc455c8072da17ac06cee386248b358947da65bd190b714f2ccb25360afea4"
},
{
"file": "h5/assets/img/ui-20261012/product-50.webp",
"source_layers": [
"8/1/2"
],
"bbox": [
1765,
15778,
2269,
16281
],
"size": [
504,
503
],
"bytes": 331924,
"sha256": "86647c8882caf62c43eafb1efe495bad3289126cab73a88c8963b7ad64ffa084"
},
{
"file": "h5/assets/img/ui-20261012/scan-waiting.webp",
"source_layers": [
"9"
],
"bbox": [
6250,
5500,
7330,
7591
],
"size": [
1080,
2091
],
"bytes": 11690,
"sha256": "6b661f3d454e9b696b70ca8846fed11243d3f53b95506c2d78b11b6b1a6d9f77"
}
],
"text_styles": [
{
"path": "0/4",
"text": "以我为始 自有表现",
"bbox": [
1502,
545,
2045,
608
],
"transform": [
0.7386429422796229,
0.0,
-1.0090361144648896e-16,
0.7386429422796231,
1772.6682649161658,
602.0113961671652
],
"runs": [
{
"font": "MiSans-Demibold",
"font_size": 90.25561,
"leading": 104.16666
},
{
"font": "MiSans-Demibold",
"font_size": 90.25561,
"leading": 104.16666
}
]
},
{
"path": "0/5",
"text": " ONE ME,\rFROM THE INSIDE OUT",
"bbox": [
1415,
391,
2133,
520
],
"transform": [
0.7386429422796229,
0.0,
-1.0090361144648896e-16,
0.7386429422796231,
1771.9296219738862,
442.37366417300353
],
"runs": [
{
"font": "MiSans-Regular",
"font_size": 90.25561,
"leading": 104.16666
},
{
"font": "MiSans-Regular",
"font_size": 90.25561,
"leading": 104.16666
}
]
},
{
"path": "0/1/1",
"text": "肌肤状态检测",
"bbox": [
1664,
1862,
2032,
1920
],
"transform": [
1.0,
0.0,
0.0,
0.9999999999999999,
1662.281376176642,
1868.3475610977566
],
"runs": [
{
"font": "MiSans-Demibold",
"font_size": 62.5,
"leading": null
},
{
"font": "MiSans-Demibold",
"font_size": 62.5,
"leading": null
}
]
},
{
"path": "1/3/0",
"text": "欢迎体验1'me\r肌肤状态评估服务!",
"bbox": [
2664,
832,
3218,
979
],
"transform": [
1.0,
0.0,
0.0,
0.9999999999999999,
2662.281376176642,
840.3475610977557
],
"runs": [
{
"font": "MiSans-Demibold",
"font_size": 66.66666,
"leading": 83.33334
},
{
"font": "MiSans-Demibold",
"font_size": 66.66666,
"leading": 83.33334
}
]
},
{
"path": "1/3/1",
"text": "我们将采集您的面部影像,为您生成专属肌肤分析与状态管理方案。所有数据严格保密,仅用于本次检测分析。",
"bbox": [
2663,
1045,
3361,
1177
],
"transform": [
0.9999999999999999,
0.0,
0.0,
1.0,
2662.281376176642,
1049.3475610977548
],
"runs": [
{
"font": "MiSans-Regular",
"font_size": 33.33333,
"leading": 50.0
},
{
"font": "MiSans-Regular",
"font_size": 33.33333,
"leading": 50.0
}
]
},
{
"path": "4/7",
"text": "请拍摄或上传\r正面及左右侧面照片",
"bbox": [
1442,
6160,
2036,
6307
],
"transform": [
1.0,
0.0,
0.0,
0.9999999999999999,
1439.281376176642,
6167.347561097756
],
"runs": [
{
"font": "MiSans-Demibold",
"font_size": 66.66666,
"leading": 83.33334
},
{
"font": "MiSans-Demibold",
"font_size": 66.66666,
"leading": 83.33334
}
]
},
{
"path": "4/8",
"text": "为使测试结果更准确,请关闭美颜/滤镜、并确保光线充足均匀。",
"bbox": [
1443,
6372,
2119,
6454
],
"transform": [
0.9999999999999999,
0.0,
0.0,
1.0,
1442.281376176642,
6376.347561097755
],
"runs": [
{
"font": "MiSans-Regular",
"font_size": 33.33333,
"leading": 50.0
},
{
"font": "MiSans-Regular",
"font_size": 33.33333,
"leading": 50.0
}
]
},
{
"path": "8/1/0/5",
"text": "以我本然有光蓄活\r双仓精华液",
"bbox": [
1362,
14850,
1627,
14932
],
"transform": [
1.7691030436028,
0.0,
0.0,
1.769103043602818,
1361.2813761766417,
14854.052217587123
],
"runs": [
{
"font": "MiSans-Semibold",
"font_size": 18.84194,
"leading": 28.26291
},
{
"font": "MiSans-Semibold",
"font_size": 18.84194,
"leading": 28.26291
}
]
},
{
"path": "8/1/0/6",
"text": "1'me 主场精华 I",
"bbox": [
1363,
14779,
1653,
14820
],
"transform": [
1.5358216667040816,
0.0,
0.0,
1.5358216667040878,
1361.2813761766417,
14784.058678621632
],
"runs": [
{
"font": "MiSans-Semibold",
"font_size": 27.12989,
"leading": 28.26291
},
{
"font": "MiSans-Semibold",
"font_size": 27.12989,
"leading": 28.26291
}
]
}
],
"shape_metrics": [
{
"path": "0/3/0",
"bbox": [
1516,
1971,
2038,
2083
],
"corner_radius_psd_px": 20.000065
},
{
"path": "0/2/0",
"bbox": [
1516,
2104,
2038,
2216
],
"corner_radius_psd_px": 20.000065
},
{
"path": "1/2/0",
"bbox": [
2753,
1410,
3275,
1522
],
"corner_radius_psd_px": 20.000065
},
{
"path": "4/2/0",
"bbox": [
1517,
6604,
2039,
6716
],
"corner_radius_psd_px": 20.000065
},
{
"path": "8/1/0/0",
"bbox": [
1285,
14677,
2269,
15180
],
"corner_radius_psd_px": 15.000158
},
{
"path": "1/1",
"bbox": [
2571,
719,
3458,
1621
],
"corner_radius_psd_px": 24.999972
},
{
"path": "4/1",
"bbox": [
1334,
5971,
2221,
6873
],
"corner_radius_psd_px": 24.999972
}
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

@@ -1,40 +0,0 @@
{
"source": "new_feedback/第三轮反馈20261012/UI外发版10.09.psd",
"source_sha256": "c7698f5900adc7476286818450d928e8fa2ce2e58cda09375ff2b861629fd58f",
"source_page": "9",
"hidden_scan_layer": "9/2/2",
"viewport": [
6250,
5500,
7330,
7591
],
"face_bbox": [
155,
426,
926,
1417
],
"cycle_ms": 1000,
"yellow": "#F5F078",
"assets": [
{
"file": "h5/assets/img/ui-20261012/scan-base.webp",
"size": [
1080,
2091
],
"bytes": 6688,
"sha256": "08f8e75634691d4329210188bd56472892d8152de0d194c9358f82fda6197ddf"
},
{
"file": "h5/assets/img/ui-20261012/scan-face-mask.png",
"size": [
1080,
2091
],
"bytes": 16417,
"sha256": "d9c729600b6141a3977e38a121f680c20c6b543a6828b1d38cd5f9878d311008"
}
]
}
-56
View File
@@ -1,56 +0,0 @@
# 10.09 新版 H5 实施与验收
更新:2026-10-12。
## 按确认项实现
- 保持 H5,无额外网页导航栏,不仿造系统/微信顶部栏。
- 登录在首页之前;复用现有协议弹层。微信网页授权链路已实现,当前内网使用本机浏览器身份,公网限制与部署见《微信登录接入与公网部署说明》。
- 首页更新口号、背景和品牌图,增加「我的报告」。修正重复入口、出镜错字。
- 我的报告独立页面,数量、日期、查看详情、空/失败状态;读取当前账号最近 5 份后端报告。
- 档案页换用新版背景和五类肤质插画,保留原选择器和校验。
- 相机轮廓与眼鼻定位虚线从 PSD 素材提取,前→右→左流程、自动抓拍、降级、语音和前后摄像头逻辑保持。
- 汇总卡合并,名称为「生物可视年龄」「紧塑力」「透亮感」「稳韧力」,不照抄设计样例中的数值。
- 七项视图分成三个独立 Tab 组:轮廓/皱纹;肤色/平滑度/水分;泛红/痘痘。使用真实检测图层或用户照片,不把设计里的模特检测图当成检测结果。
- 根据 `reference/AI测肤报告页话术修改.md` 生成新结论和护理建议。无效字段不冒充 0,无图层明确说明。
- 只显示原算法选中的一款主场精华 I / II / III,不可点击,移除「了解更多」占位入口。
- MiSans 官方原始 Web 字体本地提供,未改造字体文件;「我的报告」底部注明字体使用。
## 文档未定义部分的实施口径
话术文档没有新增计分公式或阈值,因此原六分类/三维度评分、肌龄计算不变。2026-10-12 经用户确认,精华推荐另按[肤龄基准与边界调整](产品推荐规则-肤龄版.md)实施,替代原三重判据;原始肌龄和展示肌龄在后台同时展示,历史快照不重算。旧分档「预警/改善/良好」按低/中/高顺序映射为新文案的「改善/良好/优秀」,后台同步此口径。肤色和水分拆分展示,但继续共享原 `tone` 分类的分档,**不是新增独立评分算法**。
痘痘话术按真实脓包/结节计数决定是否输出中重度皮损说明;没有计数不宣称「未检出」。当真实计数与高分模板冲突时,展示层选择可反映计数的文案,不改变原分数。
护理建议按原六分类得分选取最需要关注的两项,拼接文档对应的「护理 + 生活方式」;若命中肤色水润,分别展示肤色与水分建议,可能为三段。设计里的示例两段不作为截断真实文本的硬限制。
历史详情读取保存时的 `vm`、`presentation`、照片、图层,不用当前评分/话术重新生成历史数据。图像合成有渲染版本防护,切换报告时不会串用上一份图片。
## 验证命令
```bash
node h5/js/skin-score.js
node h5/test/regression.js
node h5/test/recommendation.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
@@ -1,25 +0,0 @@
# 提交前 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 元数据。代码、运行素材、文案来源、测试和部署说明一起提交,便于服务器复现。
@@ -1,195 +0,0 @@
# 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 随账号条件落地。报告结构和新增身份/历史能力是主要工作量,字体和相机坐标是还原精度的主要风险。
-67
View File
@@ -1,67 +0,0 @@
# 产品推荐规则:肤龄基准与边界调整
状态:2026-10-12 用户已确认三个边界条件;已实现。规则版本:`2026-10-12-skin-age-v1`。
## 已明确的要求
- 基准只取 Face++ 返回的原始 `skin_age`,不取实际年龄或修正后的展示肤龄。
- 基础分组:肤龄小于 35 岁为 25+(主场精华 I),35 至不足 50 岁为 35+(II),50 岁及以上为 50+(III)。24 岁等不足 25 岁的检测结果也归 I。
- 肤龄小于 32 岁,固定推荐 I,即使轮廓或皱纹得分低,也不触发升级。
- 删除原来的实际年龄组、六分类均分、最差分类三重判据。
- 边界附近结合三维度评分调整:紧塑力为必要条件,另外一个达标维度可为透亮感或稳韧力;不能仅因为另外两个维度高而降档。
- 37 岁肌龄、仅存在暗沉问题的案例,应允许推荐 I。
- 每份新报告仍只推荐一款;评分公式、检测流程和已有报告快照不因本次规则调整而改写。
- 原始肤龄缺失或无效时,不回退实际年龄推测产品;需要明确显示本次无法推荐。
## 已确认的三个条件
1. 只在 35±3 岁及 50±3 岁范围内调整,范围外只按肤龄。
2. 50 岁边界与 35 岁同样处理:47~不足50 岁紧塑力低于 8 分升至 III,50~53 岁紧塑力至少 9 分且另一维度至少 9 分降至 II。
3. 「7+最低档」为低于 8 分;「9+」为大于等于 9 分,恰好 8 分不升档,恰好 9 分可以满足降档条件。
## 决策顺序
年龄支持小数,区间严格按下表执行:
| 原始肤龄 | 默认产品 | 可调整条件 |
|---|---|---|
| 小于 32 | I | 固定,不升档 |
| 32~不足35 | I | 紧塑力低于8,升为II |
| 35~38(含38) | II | 紧塑力至少9,且透亮感/稳韧力任一至少9,降为I |
| 大于38~不足47 | II | 按肤龄,不调整 |
| 47~不足50 | II | 紧塑力低于8,升为III |
| 50~53(含53) | III | 紧塑力至少9,且透亮感/稳韧力任一至少9,降为II |
| 大于53 | III | 按肤龄,不调整 |
调整最多一档。没有足够的必要维度数据证明满足调整条件时,保持肤龄基础档;不把缺失值当成低分。
比较分数沿用评分引擎的三维度原始 `S=7+3×P/100`,不先进行前端一位小数或 VM 两位小数舍入。例如 7.99999 小于 8,8.99999 小于 9。原六分类和三维度评分公式、低/中/高档位阈值均不变;推荐阈值与档位文案阈值是不同概念。
## 后台与前端一致性
- 后台列表新增「肌龄(原始 / 展示)」;档案里的年龄明确为实际年龄。
- 名称统一为紧塑力、透亮感、稳韧力;列表显示与 H5 相同的一位小数分数。内部旧档位 `预警/改善/良好` 映射成 `改善/良好/优秀`,筛选参数仍传原值,避免改写旧数据或破坏统计。
- 新记录同时保存 `skin_age_display`、`recommendation` 和前端 `presentation`。后台详情展示基础档、最终档、未舍入的判定分、推荐原因与规则版本;七项结论和护理建议直接使用同一份前端快照。
- 旧记录没有新规则元数据时,明确显示「旧版规则(历史记录)」,不按新规则重新推荐。后台详情可读取原账户已保存的前端展示快照;无快照则标注旧版文案。旧记录未存展示肌龄时,按原有实际年龄±3规则只读补全展示值。
- CSV 同步提供两种肌龄、统一的新档位名、推荐版本和原因。
## 实施与验证范围
- `h5/js/skin-score.js`:推荐决策、产品组别、推荐原因及相关综合文案;保留原评分算法。
- `h5/js/report-ui.js`:前后台共用名称、档位、三款产品映射;H5 无有效肤龄时隐藏具体产品并说明原因。
- 更新引擎自测和 Excel 回归中的产品相关断言;原始 Excel 保留为旧算法参照,不改写评分真值来掩盖差异。
- 新增边界测试:24岁且轮廓/皱纹低分;31.99/32/34.99/35/38/38.01;46.99/47/49.99/50/53/53.01;紧塑力7.99/8/8.99/9;另两个维度分别达标;必要条件不满足;实际年龄改变不影响推荐;原始肤龄和显示肤龄不同;维度或肤龄缺失。
- 验证新报告保存与重开后产品一致,已有报告仍读取原有快照。
- 本次不调整展示肤龄的实际年龄±3岁修正规则,后台并列展示两者,推荐只使用原始肤龄。
验证命令:
```bash
node h5/test/recommendation.js
node h5/js/skin-score.js
node h5/test/regression.js
node h5/test/accounts.js
node h5/test/report-persistence.mjs
```
已通过 126 个推荐用例、83 条评分引擎自测、86 条真值回归。隔离 HTTP + Chromium 验证前后台原始/展示肌龄、三维度评分、推荐产品、七项结论、护理建议、筛选与 CSV 一致;验证保存重开、旧报告快照不改写、无肤龄时不残留上一款产品。全部使用样本上游,不调用收费 Face++。
@@ -1,29 +0,0 @@
# 原始肌龄显示与鸿蒙滚轮兼容
## 范围
- 生物可视年龄直接展示算法原始肌龄,取消实际年龄 ±3 的展示修正。原始肌龄缺失显示 `--`,不以实际年龄或旧展示值补齐,不额外四舍五入。
- 新报告 `skinAgeDisplay` 与 `skinAgeRaw` 相同,保留兼容字段 `ageClampNote` 但值为空。推荐规则、评分和其他话术不变。
- 历史报告回看优先读取快照 `vm.skinAgeRaw`;更老的快照缺该字段时,从保存的 `payload.result.skin_age` 读取。忽略旧的钳制展示值,不改写存量快照,不重算历史推荐/文案。后台列表、详情、CSV 的展示肌龄也改为读取原始肌龄,避免前后台不一致。
- `mobile-select@1.4.0` 原来通过 UA 字符串选择 touch/mouse,无法识别不带 Android 的 OpenHarmony/ArkWeb。保留上游版本与 MIT 声明,添加本地补丁:通过 `navigator.maxTouchPoints > 0` 或 `ontouchstart` 能力选择触摸事件,无触摸能力则使用鼠标事件;不再按系统名称判断。
- 同时按事件的 `touches/changedTouches` 读取坐标,不依赖全局 `TouchEvent` 构造函数,避免无该构造函数的鼠标环境报错。弹层挂载、页面禁滑和滚轮联动逻辑不变。
## 回归
```bash
node h5/test/raw-skin-age.js
node h5/js/skin-score.js
node h5/test/recommendation.js
node h5/test/regression.js
node h5/test/report-persistence.mjs
node h5/test/harmony-picker.mjs
node h5/test/profile-interaction.mjs
node h5/test/guest-privacy.mjs
node h5/test/report-touch-layout.mjs
```
鸿蒙专项使用 Chromium 的真实触摸/鼠标分发配合不同 UA 与能力配置,逐项验证年、月、省、市四轮、地区联动、确认回填、重开定位和表单提交。覆盖 Android 触摸、OpenHarmony 5、OpenHarmony 6+微信、桌面 UA 的触摸设备、无 TouchEvent 构造函数的桌面鼠标、Android UA 的无触摸环境。
这属于 UA/能力兼容回归,不等同于鸿蒙真机或 ArkWeb 内核验证。测试使用隔离临时目录或拦截账号请求,不写线上报告,不调用付费检测。历史报告测试故意保留旧展示值 57 岁,确认 H5/后台改显示原始肌龄且原文件字节不变。
用户已确认发版。本次与《微信退出登录-2026-10-13.md》的修改一起提交,采用 Git bundle 快进同步到 `/home/ubuntu/juzi`,重启 `juzi-h5.service` 后校验线上资源、健康与浏览器交互。不代用户推送 origin,不改写既有报告或调用线上付费检测。摄像头切换不在本次修改范围内。
@@ -1,36 +0,0 @@
# 基础信息记忆与肤质拖动
> 2026-10-13 调整:以下偏好缓存仅对微信登录生效。游客仅保留当前页面操作中的临时表单值,不写缓存、不回填历史;刷新后重新填写。详见《游客不留存与弹窗护理间距调整-2026-10-13.md》。
## 范围
- 出生年月、性别、地区每次点滚轮“确定”即保存,不必拍照或提交报告。
- 日常肤质切换后也保存。再次进入基础信息页,包括刷新、返回、重新登录同一账号时,默认使用本机上次已确认的值;滚轮重新打开也定位到原选择。
- 保存出生年月而非固定年龄,进入页面和提交前按当前年月重新计算实际年龄。
- 使用当前登录账号的 `kind + id` 隔离本机缓存。切换微信/游客或另一个账号时,页面值与滚轮位置一起重置/恢复,不串用其他账号信息。
- 这是本机浏览器偏好缓存,不新增服务端档案同步接口;同一微信账号换手机仍可看服务器报告,但本次新增的基础信息默认值不跨设备。清除浏览器数据后需重新填写。
- 老版本没有单独保存出生年月,无法准确反推出原选择;更新后需确认一次,从此开始记住。缓存被禁用或容量不足时保持当前页面可用,在该页面内记忆,不保证刷新后保留。
- 缓存只包含出生年月、性别、省市、肤质序号,不复制身份凭据、照片、报告。
## 肤质交互
- 水平方向拖动时,图片、名称与说明一起实时跟随手指,不再等松手才切换。
- 松手按距离/轻扫速度吸附到相应选项;短距离慢拖回原项。
- 首尾拖动有弹性阻力,松手回到有效选项;系统取消手势时复位。
- 横竖方向锁定,保留 `touch-action: pan-y`,不阻塞页面上下滚动;屏幕尺寸变化后保持选项对齐。
- 原有箭头、圆点保留;补充左右方向键支持。
- 不改变 PSD 素材、颜色、页面布局、拍摄约束、评分或推荐规则。
## 回归命令
```bash
node h5/test/profile-store.js
node h5/test/profile-interaction.mjs
H5_BASE_URL=https://1me.xajuzi.com/state/ node h5/test/profile-interaction.mjs
```
浏览器测试使用真实页面与 mobile-select 控件,以模拟账号和真实触摸事件检查恢复、账号隔离、跟手位移、吸附、短拖、轻扫、首尾阻力、系统取消、纵向手势以及不同屏宽。测试只跳过字体下载、拦截登录会话并暴露滚轮实例用于选择测试值;所有非 GET 请求均阻止,不会新增线上账号、报告或付费检测调用。
本地已通过上述两套新增测试,以及第四轮反馈浏览器闭环、登录加载与超时、报告持久化、账号/OAuth 隔离、真实本地模型自动三连拍与最终 JPEG 复验、推荐 126 用例及算法真值 86 断言。
部署目标为 `ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`,基线 `c9352fe`。沿用 Git bundle 快进同步,不代用户推送 origin,不改服务器环境配置或历史数据。上线后核对静态文件哈希、服务健康、匿名访问保护,并执行同一套只读模拟账号浏览器测试。
-67
View File
@@ -1,67 +0,0 @@
# 客户反馈修改(2026-10-12)
依据:`feedback/傅艳NEW与项思炼的会话 2026年10月12日/傅艳NEW与项思炼的会话 2026年10月12日.md` 及其 6 张截图。本文仅处理本次客户反馈,不修改评分公式、肤龄显示规则或产品推荐规则。
## 逐项处理
| 客户反馈 | 处理 |
| --- | --- |
| 报告 Tab 同时支持滑动、点击 | 三组维度卡分别支持横向手势及点击;纵向滚动不切换,边界不循环。保留键盘方向键、Home/End 操作。 |
| 检测图脸部放大,同时保留点开放大 | 根据接口原始人脸矩形统一裁切照片、增强图和标记的展示区域,保留额头、下巴余量;七张检测图均处理,点开放大保留。无人脸矩形或矩形无效时展示原图。上传原图、检测输入、存档照片不裁切。 |
| 皱纹分区详细说明 | 展示 12 个真实分区的 9 项原始指标,缺失显示「未获取」,0 保留为 0。抬头纹和额头纹在现有数据中同属 `forehead_wrinkle_info`,合并为「抬头纹(额头纹)」,不虚构第 13 区。左右以本人为准。 |
| 平滑度图有框,但文字说无毛孔、黑头 | 原图错误使用色斑、痣、痤疮框。改为真实的毛孔、黑头增强图,并说明颜色及其不代表严重程度。缺图不绘制其他问题框。总体评分优秀但局部计数大于 0 时明确列出计数,不再写「无明显」。评分与档位本身不变。 |
| 黄色按钮色号不一致 | 最新 PSD 按钮矢量填色与导出像素均为 `#F5F078`,当前按钮也使用该色;正常按钮没有额外透明度/滤镜。傅艳已确认暂按 PSD 的 `#F5F078`,保持现有色值。屏幕色彩模式可能影响观感,不能据截图猜测新色。 |
| 产品名固定断句 | 三款副标题第一行分别为「以我本然有光蓄活」「以我自在有势挺括」「以我从容有态构塑」,第二行统一「双仓精华液」,独立块且不自动换行。 |
| 链接卡顿、拍摄提示不符 | 卡顿已由上一轮首屏延迟加载与静态缓存优化处理,本次复测无回退。拍摄提示按最新 PSD 改为「为使测试结果更准确,请关闭美颜/滤镜、并确保光线充足均匀。」 |
| 字号不随手机宽度缩放 | 原来按 `--u` 缩放的字号改为 375 宽设计基准的固定 CSS px;布局间距和图片仍适应屏宽。既有文字自动放大控制保留。不承诺不同屏幕的物理毫米大小或系统强制辅助缩放完全相同。 |
## 皱纹数据说明
12 区:抬头纹(额头纹)、左右法令纹、左右鱼尾纹、左右眼部细纹、左右嘴角纹、眉间纹、左右脸颊纹。
9 项:皱纹分、严重等级、深纹条数、浅纹条数、标准化长度、标准化深度、像素密度、面积比例、深纹比例。
数值来自接口原始字段,最多显示四位小数;比例保留接口原值,不擅自转成百分比或补单位。分区深浅纹条数仅在对应指标缺失时使用接口分区计数回退,其余缺失不推算。不对原始数据及评分模型作任何写入。
新生成报告由后端保存新版文案快照,后台与前端读取同一份内容。已有历史报告继续保留当时的文案和推荐快照,不批量重算、不修改历史记录;展示图片可依据已保存原图与矩形使用新的裁切方式。验收新增皱纹话术请生成新报告,不以旧快照作为新版话术验证依据。
## 验证
```bash
node h5/test/customer-feedback.js
H5_ARTIFACT_DIR=/tmp/juzi-feedback-customer-20261012 node h5/test/customer-feedback.mjs
node h5/test/recommendation.js
node h5/test/regression.js
node h5/test/accounts.js
node h5/test/report-persistence.mjs
node h5/test/ui-20261009.mjs
node h5/test/login-performance.mjs
node h5/test/wechat-browser.mjs
node h5/test/analyze-timeout.js
node h5/test/browser-failures.mjs
node h5/test/e2e-browser.mjs
```
专项验证包括真实浏览器触摸事件、三组独立切换、纵滚不误触、横滑不误开放大图、点开放大仍正常、七图裁切及边界容错、12 区真实指标和缺失值、部分增强图缺失、三款产品在 320/375/390/414/480 五种宽度下固定两行且无溢出。专项截图见上述临时目录。
登录性能复测:150 ms 网络延迟、约 2 Mbps 下载、CPU 四倍降速,冷登录可操作约 1636 ms、静态资源编码后 262618 字节;登录仍不加载人脸引擎、模型或完整字体。该结果是开发机模拟观测,不保证所有手机耗时。微信回归使用模拟授权上游,实际 HTTPS Cookie 和跨设备身份隔离均验证,不代表重新完成一次真人微信授权。
上述测试全部通过,包含 126 个产品推荐案例、86 条评分真值断言;UI 回归同时刷新了 `design/ui-20261009/verification/` 内的验收截图。已执行 `graphify update .` 更新代码关系图。
测试使用样例、隔离数据目录或只读演示页,不调用收费 Face++,不修改生产账号或历史报告。确认本地没有近 180 秒进行中的检测后,已重启本地 H5 服务以加载后端新版话术,健康检查正常。黄色按钮色值已确认,无其他待确认项。
提交仅包含代码、修改说明、代码关系图及验收截图,不包含客户聊天原文和附件。公网部署沿用既有 Git bundle 快进同步方式,不推送远程仓库,不迁移或覆盖 `h5/data`,不修改微信凭据、nginx 或后台访问保护。
## 公网部署与复测
2026-10-12 已将功能提交 `d7ae748` 从本机同步至 `ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`,从 `3193a4b` 快进更新。确认近 180 秒无进行中的检测后重启 `juzi-h5.service`;Node 服务与 nginx 均正常,健康检查成功,服务无自动重启。服务器上重新运行专项纯函数、126 个推荐案例、账号测试全部通过。
通过 `https://1me.xajuzi.com/state/` 完成以下复测:
- 公网浏览器专项测试全部通过:真实触摸切换、纵向滚动不误切、点开放大、七张人脸裁切图、12 区皱纹文案、三款产品在五种屏宽下固定两行、增强图缺失提示及无脚本异常。截图目录 `/tmp/juzi-online-feedback-d7ae748`。使用只读样例页,不发起收费检测。
- HTML、应用脚本、报告文案脚本和两份样式的公网内容与本地逐字节一致,gzip、ETag/304 校验通过。功能版本的全部跟踪文件哈希清单在本地和服务器均为 `a45146c325004eecf5448d394d85ccc507e0e8f60798637829917a42b7c3a519`。
- 微信配置仍启用,匿名会话无用户,私有会话接口保持 `no-store`。匿名报告、后台页面和后台接口返回 401;数据、源码和测试目录返回 404。没有发起新的真人微信授权,也未改动账号身份。
- 部署前后检测记录均为 105 条,近 180 秒进行中的检测均为 0;不创建生产测试账号、报告,不清理历史数据。
- 公网冷登录编码资源为 262640 字节,未提前加载字体、人脸引擎或模型。并发专项测试期间一次可操作耗时 5341 ms;专项完成后,三个全新浏览器上下文分别为 384、1185、299 ms,HTML 首字节分别为 245、737、220 ms。存在网络波动,不将模拟或单次观测作为手机耗时保证。
本记录随后以文档提交同步到服务器,不需要再次重启应用。远程仓库未推送,仍由傅艳自行 push。
@@ -1,89 +0,0 @@
# 第三轮反馈:PSD 对齐、验收及上线记录
日期:2026-10-12。依据 `new_feedback/第三轮反馈20261012` 的客户会话、四张批注及新版 `UI外发版10.09.psd`。本轮已完成本地开发、Git 提交及生产部署;按此前约定未推送 origin,由用户自行推送。
## 已完成
| 范围 | 实现 |
| --- | --- |
| 首页/引导背景 | 直接导出 PSD 中三行口号、Logo 与中文组合,保留原始字形、字重及可见高度比例;首页两个按钮的静态文字也从 PSD 导出,不再依赖手机系统字体。 |
| 介绍弹窗 | 完全采用用户确认的 PSD 原文,按原稿校准弹窗位置、标题、正文、勾选区及按钮;服务端保存和回看保持不变。 |
| 拍照引导 | 固定设计稿的两行断句、字号及文本栏;弹窗固定约 308×313 CSS px,320px 窄屏也能完整展示,不机械缩小文字。 |
| 产品卡 | 使用 Semibold 原字体,标题约 14.47px、名称约 11.57px;校准左侧约 26.74px 留白、品牌标识及纵向位置。右图按 PSD 白卡的实际可见区域导出,不再二次居中裁切。 |
| 生成报告等待 | 三张照片拍完后显示 PSD 原始黑底、白色人脸、黄色扫描区和「检测中…」。相册/翻转图标仅是图片内容,不可点击、不可聚焦;保留明确取消、返回、失败恢复及请求完成后的报告跳转。 |
产品仍只展示算法推荐的一款;没有修改评分、肤龄、推荐规则、三视角顺序或自动拍摄阈值。历史报告保留原推荐和原文案,仅按已有产品档位更新展示图片的裁切,不回写历史数据。
用户确认的弹窗原文:
> 我们将采集您的面部影像,为您生成专属肌肤分析与状态管理方案。所有数据严格保密,仅用于本次检测分析。
引导正文的 PSD 断点(包括「确/保」之间的换行):
```text
为使测试结果更准确,请关闭美颜/滤镜、并确
保光线充足均匀。
```
## 原稿与导出可追溯性
- 新 PSD 为 7330×16411、11 个顶层分组,新增第 9 号「扫描」,原「登录」变为第 10 号。旧导出器改为按唯一名称定位「登录」,拒绝缺失或重名,避免切图串页。
- 本轮选择性导出脚本:`tools/export_third_feedback_assets.py`。运行方式:
```bash
python3 tools/export_third_feedback_assets.py 'new_feedback/第三轮反馈20261012/UI外发版10.09.psd'
```
- 原 PSD SHA-256:`c7698f5900adc7476286818450d928e8fa2ce2e58cda09375ff2b861629fd58f`。
- `design/ui-20261012/manifest.json` 记录源文件校验、图层路径、原始坐标、字体及变换矩阵、输出尺寸和逐资源 SHA-256。测量包含文字图层的缩放,不直接把原始 FontSize 当最终字号。
- 另读取矢量路径确定原稿圆角:弹窗 25 个设计像素、按钮 20px、产品卡 15px(375px 基准分别约 8.68/6.94/5.21 CSS px),不是继续沿用旧版估计值;产品卡宽高按 984×503 的原稿比例校准。
- 八份前端资源位于 `h5/assets/img/ui-20261012/`;PNG/无损 WebP 均来自 PSD,不使用生成式替代图、不改人物或产品包装。原 10.09 资源和字体文件保留不动。
- 扫描页须整体合成,保留跨图层剪贴依赖,再裁掉 248px 微信原生顶栏;单独导出图标组会漏掉人脸。导出器及浏览器测试都检查白色人脸、黄色下半脸像素。
- 原稿预览保存在 `design/ui-20261012/page-{0,1,4,9}.webp`,仅用于核对,不将整个交互页面替换为背景截图。微信原生导航由宿主提供,不叠加进 H5。
- 等待画面保持原始长宽比,异形屏用黑色留白适配;额外的「取消」为保留已有功能的必要入口。不新增虚构百分比、扫描动画或固定长时间等待,沿用原有至少 1.2 秒防闪及 150 秒请求预算。
- 扫描图未加载或加载失败时仍显示「检测中…」文字并可取消,不留下无提示黑屏;正常加载后仅展示原稿文字,不重复叠字。
- 静态品牌图规避系统字体差异;其余动态文字使用完整原始 MiSans,保留 `font-display: swap`。小字号开启几何精度渲染,减少浏览器将小数像素字宽取整造成的断行偏差;不同系统的文字抗锯齿仍可能有细微区别。
## 本地验证
已通过以下检查,未调用收费 Face++ 或改动线上账号、照片、报告:
- 第三轮专项:源资源校验/PSD 字体与原文、320/375/390/414/480px 弹窗和产品排版,三款推荐产品、固定断行、字体失败降级、短视口及等待页六种尺寸;实际三张上传推进、装饰图标、键盘焦点、取消/迟到响应、失败重试、成功进入报告。
- 第二轮专项:全屏相机、三种圆角轮廓、五官辅助线、震动安全降级、450ms 自动抓拍条件、协议及报告实际字体、首屏无大字体/模型请求。
- 原反馈回归:报告图放大、三个维度独立滑动切换、上下滚动、七张真实数据可视化及皱纹/毛孔文案。
- 推荐规则 126 个用例、原算法 86 条断言,以及 150 秒超时/迟到回调单测。
- 隔离服务器的报告持久化:后台/H5/CSV 一致、最新五份报告、用户隔离、历史快照不回写,包含旧图片路径升级展示的验证。
- 登录及模拟微信:隔离 HTTPS `/state/` 回调、Secure cookie、账号切换、跨设备同账号和不同账号隔离;不是对真实手机授权的替代验收。
- 登录性能回归:150ms 延迟、约 2Mbps 下载及 4 倍 CPU 降速下冷启动约 **1.64 秒**、资源 **264610 字节**;新增扫描图约 11.7KB,在进入档案/相机后才加载,不竞争登录首屏。
- 切图映射 3 个单测、JS/Python 语法及 diff 空白检查。按项目约定执行 `graphify update .`(AST 更新,无付费语义提取)。
主要复验命令:
```bash
python3 tools/test_export_psd_assets.py
H5_ARTIFACT_DIR=/tmp/juzi-third-final node h5/test/customer-feedback-third.mjs
node h5/test/customer-feedback-second.js
node h5/test/customer-feedback-second.mjs
node h5/test/customer-feedback.js
node h5/test/customer-feedback.mjs
node h5/test/recommendation.js
node h5/test/regression.js
node h5/test/analyze-timeout.js
node h5/test/report-persistence.mjs
node h5/test/accounts.js
node h5/test/login-performance.mjs
node h5/test/wechat-browser.mjs
```
## 生产部署及只读验收
- 功能提交:`c7b085e795f21565a9802896041b447970f44ab9`(`feat(h5): align third feedback with latest PSD and scanning screen`)。
- 部署目标:`ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`;页面为 <https://1me.xajuzi.com/state/>。部署前确认服务器工作区干净,与本地基线 `f3e7eac` 一致,通过 Git bundle 快进更新,不覆盖服务器私有配置或用户数据。
- 因后端启动时加载 `report-ui.js`,同步代码后重启 `juzi-h5.service`,保证前后端使用同一版本。服务 `active`、自动重启次数 `NRestarts=0`,健康接口返回 `ok:true`;检查时最近 15 分钟没有 systemd 错误级日志。
- 线上首页、两个 JS 模块、新 CSS 及八份新素材均返回 200,与本地逐文件 SHA-256 一致,并带有 `Cache-Control: no-cache`。
- 线上第三轮浏览器专项全部通过:五种宽度弹窗/断行/产品排版、三款产品、三张照片推进至扫描页、白色人脸和黄色扫描区、六种视口、装饰图标、取消/迟到响应、失败重试和成功报告、字体及扫描图失败降级;没有页面 JS 异常。检查了线上首页、等待画面和产品卡截图。
- 线上第二轮浏览器回归也通过:首屏不请求完整字体/人脸引擎、协议字体实际加载、全屏相机和三种圆角轮廓/五官辅助线、报告数字及标题的真实 PSD 字体、五种宽度无溢出;没有页面 JS 异常。
- 访问控制检查:未登录报告接口、后台页面和统计接口均返回 401;私有身份文件和 `server.js` 返回 404;微信登录配置仍启用。
- 生产浏览器回归使用内存中的登录/分析响应及本地示例图片,不提交真实检测、不调用收费 Face++、不创建或改动线上账号和报告;不能替代真实手机微信授权及摄像头验收。
仍需用户在真实手机微信中做最终视觉/相机验收。客户反馈原件及 PSD 未修改、未纳入提交;服务器凭据、环境配置、已有照片和报告保持不动。
@@ -1,82 +0,0 @@
# 12 日第二批:明确项修改
依据用户提供的 `12 日第二批.docx`(正文与 6 张截图)、随后补充的首页高清批注图及最新 `UI外发版10.09.psd`。原第 3 张首页截图仅 73×160 像素,未猜测;收到高清图后补齐下面两项。
## 已修改
### 首页高清批注
- 将三行口号中的中文「以我为始 自有表现」独立为 700 字重,英文继续使用 400 字重,保留三行断句与位置。PSD 对应中文 `0/4` 为 Demibold、英文 `0/5` 为 Regular,确实有粗细区别。
- 放大底部「肌肤状态检测」到 24 CSS px、700 字重,与原始 Logo 约 26 CSS px 的可见高度对齐;Logo 保持原图宽高比。Logo 与文字均固定 CSS px,不再因屏宽缩放 Logo 而让二者比例失衡。
- 首页继续使用系统字体表达字重区别,不提前下载约 5 MB 的完整 MiSans 字体;不改动或子集化字体。系统字体字形的细微差别仍依手机系统而定。
- 在 320、375、390、414、480 五种屏宽验证:品牌行不溢出,口号仍三行,登录状态不遮挡口号,首屏不新增字体或检测引擎请求。
### 拍照展示
- 去掉人脸外轮廓的白色描边,以及原来无脸呼吸/合格变绿的轮廓描边;保留明暗镂空、五官虚线、扫描提示和「保持不动」反馈。
- 视频由 85% 缩小预览恢复为铺满视口,避免外侧矩形取景边界;镜像仍保留。屏幕人脸中心坐标的缩放系数同步为 1,距离、姿态、光线判定阈值不变。
- 对 PSD 导出的折线轮廓做最大 2 CSS px 的局部圆角化,使用二次曲线、不过冲、不改变轮廓坐标系。镂空与扫描裁切使用同一份平滑轮廓。原始 `CameraGeometry` 不修改。
- 原始视频抓帧、上传图片、报告图片处理与评分/推荐逻辑不变。
### 准备捕捉提醒
原来仅在补光抓拍瞬间请求 30 ms 震动,改为首次满足检测条件、开始「保持不动」时请求 `[70, 40, 70]` 两次短震动。连续合格 450 ms 后仍按原流程自动抓拍,不增加倒计时。抖动重试时最多每两秒请求一次,每步重置。
实时相机的手动快门模式仍在点击抓拍时请求提醒;自动模式不会在抓拍瞬间再重复震动。
API 不存在、返回 false 或抛出异常时安全跳过,不能因震动失败卡住拍摄。此处没有接入未经验证的微信私有接口,也不声称所有 iPhone/微信环境均可震动。振动接口存在浏览器、用户激活和系统设置限制,实效必须在手机微信上测试;参见 [MDN Navigator.vibrate](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate)。保留原有文字、语音和补光反馈。
### 字重
直接读取 PSD 字体元数据,明确区分而非将所有文字一起加粗:
| 位置 | PSD 图层 | 原始字体 |
| --- | --- | --- |
| 协议弹窗标题 | `1/3/0` | MiSans-Demibold |
| 拍照引导弹窗标题 | `4/7` | MiSans-Demibold |
| 正/右/左拍照步骤 | `5/3`、`6/2`、`7/2` | MiSans-Demibold |
| 综合评分、肌龄 | `8/12/2`、`8/12/3` | MiSans-Demibold |
| 三维度数字 | `8/12/7/2`、`8/12/7/9`、`8/12/7/13` | MiSans-Demibold |
| 报告标题、三维度大标题 | `8/13`、`8/9/17`、`8/10/20`、`8/11/17` | MiSans-Semibold |
| 护理建议、产品区大标题 | `8/2/0/1/0`、`8/1/3` | MiSans-Semibold |
项目原来只有 Regular、Semibold,数字和部分提示还使用 Regular 字重。现从[小米官方字体包](https://hyperos.mi.com/font/zh/download/)增加完整的原始 Demibold 文件(4994364 字节),未转换、未子集化、未修改字形;SHA-256 为 `7afe3737efaf6a137db0ef4857fbe4033a8802756485ebc7f008e96a4bdedcf2`。保留字体归属声明。
Demibold 使用独立 CSS 字体族,仅应用于本轮明确需要它的位置,避免影响原有正文、Tab 和其他 Semibold 元素。报告大标题按原始 Semibold 字形显示,不能承诺所有原本已经正确加载 Semibold 的标题都会额外变粗。
字体样式注册提前到打开协议/拍照引导弹窗时,解决首次协议弹窗尚未注册项目字体的问题。继续 `font-display: swap`,不阻塞交互;登录、首页和账号恢复仍使用系统字体,不在首屏请求完整字体或模型。新增完整字体约 5 MB,在需要的页面下载并缓存;弱网下载完成前仍可能短暂显示回退字体。固定字号与产品两行断句保持不变。
## 验证与状态
```bash
node h5/test/customer-feedback-second.js
H5_ARTIFACT_DIR=/tmp/juzi-feedback-second-final-20261012 node h5/test/customer-feedback-second.mjs
node h5/test/customer-feedback.js
H5_ARTIFACT_DIR=/tmp/juzi-feedback-second-regression node h5/test/customer-feedback.mjs
node h5/test/recommendation.js
node h5/test/analyze-timeout.js
node h5/test/login-performance.mjs
node h5/test/e2e-browser.mjs
H5_ARTIFACT_DIR=/tmp/juzi-feedback-second-ui-20261012 node h5/test/ui-20261009.mjs
```
专项测试覆盖三种轮廓的有界曲线和无原始数据修改、异常输入回退、震动缺失/拒绝/抛错容错、抓拍前触发及频率限制、原有 450 ms 自动抓拍时机;浏览器核验实际渲染字体(不仅是 CSS 数值)、五种屏宽的全屏预览与固定字号、三种状态均无轮廓描边、五官引导保留、登录首屏无大字体/模型请求。专项浏览器测试拦截会话并使用本地合成视频流,不写入后端账号、报告,也不调用收费检测。
已完成本地开发及验证,首页高清图的两处批注也已补齐,并按用户要求提交 Git、部署公网。未推送 origin,由用户自行推送。真实手机震动实效仍待确认。
## 公网部署与复核(2026-10-12,北京时间)
- 功能提交:`fe9623a`;服务器 `/home/ubuntu/juzi` 通过 Git bundle 从 `abb1c4c` 快进部署到此版本。随后同步本节部署记录及公网字体检查的测试时序修正。
- 地址:`https://1me.xajuzi.com/state/`。本轮仅变更前端资源,服务按请求读取磁盘文件,因此无需重启 Node 或 nginx;`juzi-h5.service` 持续 active,进程 PID `3481826` 未变化。
- 公网 HTML、三份 CSS、`app.js`、新增 Demibold 字体均与本地 SHA-256 一致,资源保留 `Cache-Control: no-cache`,刷新会重新校验版本。
- 健康接口 200/ok,微信配置 `wechat: true`;匿名报告接口和后台页面/统计接口均 401,源码与私有账号数据路径均 404。未修改微信私有配置、真实账号、照片和报告,也未调用收费检测。
- 专项浏览器测试分别在本地及公网通过,确认五种屏宽首页字重与视觉高度、协议/报告实际渲染字体、全屏取景/无轮廓描边/圆角与五官引导、无 JS 错误。公网测试仅拦截会话、使用浏览器本地合成视频和模拟报告,不向后端写账号或报告。
- 发现并修正测试本身的时序问题:`<link>` 插入 DOM 不代表字体声明已加载;测试先等待 `document.fonts` 注册后再检查字体。未因此更改页面行为。
- 登录性能回归通过:模拟 150 ms 延迟、约 2 Mbps 下载、4 倍 CPU 降速,冷启动约 1.66 秒、资源约 264 KB(测试环境数据,不代表所有手机实测);登录及首页没有新增字体/模型下载。
- 126 项推荐规则测试、抓拍提醒/容错测试、原反馈及超时测试通过;隔离 HTTPS 环境的模拟微信授权、跨设备报告/账号隔离和切换登录回归通过。本轮未替代真实手机微信授权或震动验收。
公网专项验证命令:
```bash
H5_BASE_URL=https://1me.xajuzi.com/state/ H5_ARTIFACT_DIR=/tmp/juzi-second-deploy-online-20261012 node h5/test/customer-feedback-second.mjs
```
@@ -1,88 +0,0 @@
# 第四轮反馈修改与验收
依据:`feedback/第四轮反馈` 的客户会话、6 张批注图及傅艳在本线程中的逐项确认,包含随后指定的皱纹三档原文。按用户要求提交及部署,不代替用户推送 origin。
## 已确认并实现
1. 登录按钮、登录成功弹窗、首页/我的报告状态及相关引导统一使用「游客登录/游客已登录」,内部仍为原 `browser` 身份,不另建账号、不丢失已有报告。明确说明游客报告仅能在当前浏览器查看、不能跨手机同步。
2. 拍摄质量在前端收紧,不新增服务端质量拦截、重拍要求或额外质量检查接口。服务端原有业务错误处理不变;仍按现有算法剔除无效数据。成功报告不显示侧脸角度无效、建议重拍等备注,后台保存完整备注及结构化质量标记。
3. 皱纹结论使用傅艳最后指定的「改善/良好/优秀」三档原文(下附)。客户正文不再附加 12 分区/9 指标长文;分区原始指标保存在结构化快照,并在受保护后台单独展示。历史报告仅显示原有结论、不再展示分区附文,不回写历史快照。评分、肤龄、推荐规则及照片视角归属不改。
4. PSD 原始画面拆为白脸底图和透明人脸遮罩,黄色扫描区约 1 秒完成一次上下往返。成功返回至少等到实际 CSS 动画完成一轮;响应慢时不额外延长等待,取消/失败不为动画延迟。相册和翻转图标依旧仅装饰、不可操作,取消入口保留。
5. 三维度评分下方恢复浅灰提示区及黄色竖线,固定两行结构:`近期优先关注:{维度名}` 与客户指定建议。根据已保存的原始维度 P 值选最低项,不使用前端一位小数排序;并列依次紧塑力、透亮感、稳韧力,缺失不作 0、全部缺失则隐藏。历史报告也按其保存分数展示,不重算、不回写历史快照。
| 最低维度 | 建议原文 |
| --- | --- |
| 紧塑力 | 强化紧塑力,提拉轮廓抚平细纹。 |
| 透亮感 | 提升透亮感,补水提亮加强防晒。 |
| 稳韧力 | 增强稳韧力,舒缓泛红强韧屏障。 |
### 皱纹(紧塑力)原文
- 【改善】全脸共检测到皱纹 {wr_cnt} 条、细纹 {fl_cnt} 条,面中、口周、眼周等区域已出现静态纹倾向,纹路已呈现固化趋势,并非临时性干纹。
- 【良好】全脸共检测到皱纹 {wr_cnt} 条、细纹 {fl_cnt} 条,面部整体平整,仅眼周或口周有细微的干纹,无明显静态深纹,纹路面积占比相对较低。
- 【优秀】面中、口周、眼周等各区域均无明显皱纹沟壑,无静态深纹与粗纹,各类纹路面积均处于极低水平,面部整体平整细腻。
缺失的计数仍标记为未获取,不伪造为 0;分档计算保持不变。
## 前端参数及限制
参数版本 `2026-10-12-fourth-v1`,集中在 `h5/js/capture-quality.js` 和 `h5/js/head-pose.js`。
| 条件 | 之前 | 本轮 |
| --- | --- | --- |
| 人脸检测置信度 | ≥0.3,取单一人脸 | ≥0.5,检查检测到的人脸数量为 1 |
| 框高/原始帧高 | 30%~68% | 34%~64% |
| 水平居中 | 偏离≤18% 屏宽 | 偏离≤12% 屏宽 |
| 完整入镜 | 没有单独边缘门限 | 检测框距原始帧边缘≥2% |
| 正脸 yaw/pitch | ≤15°/18° | ≤10°/12° |
| 侧脸幅度/pitch | 28°~75°/≤20° | 35°~65°/≤15° |
| 歪头 roll | 不判断 | ≤10° |
| 脸部平均亮度 | 65~235 | 75~225 |
| 稳定累计 | 450ms,短暂漏检不打断 | ≥650ms 且≥3 合格帧;任何漏检/异常打断,帧间隔>2000ms 打断 |
| 稳定期间漂移 | 未单独判断 | 相对起始合格帧 yaw/pitch≤5°,中心 x/y≤原帧 3.5%,框高占比变化≤4.5 个百分点 |
| 最终 JPEG | 实时抓拍后直接推进 | 抓拍后本地复验通过才推进 |
系统相机/相册文件使用同样的单人、完整入镜、距离、角度、光线门限;由于系统照片可能已镜像,沿用不判断左右方向的兼容方式,并记录 `direction_checked:false`。模型加载中最多等待 8 秒;模型确实不可用时保留原有手动/文件降级通路,并记录 `unchecked/model-unavailable`,不伪称已校验。
这些角度是 68 点几何经验估计,不是服务端 `jawline_quality` 的直接替代;只能尽量提高合格率,不能承诺手机实拍 100% 通过。仍需提测收集不同机型、光线和转头方式的样本后校准。未修改取景轮廓、自动拍摄三步顺序或语音资源。
真实本地识别模型的自动流程测试发现:无硬件加速时每帧推理约 1.05 秒,若将间隔上限设置为 1 秒会一直停留在「保持不动」。因此最终上限采用 2 秒;650ms/至少 3 帧及全部质量/漂移约束不变,慢设备按实际推理耗时累计,不为抢速度跳过合格帧。
## 后台校准留痕
- 现有测肤请求携带参数版本、三视角的本地观测(yaw/pitch/roll、置信度、亮度、框比例及中心位置),不新增网络往返、不向前端下发服务端私钥。
- 后端仅接收限定字段和有界数值,明确标记 `client-untrusted`。当前参数版本对应的配置快照一同保留,避免以后调整参数后无法追溯。
- `capture_quality` 单独保存接口左右侧脸的 quality、下颌线角度、valid/invalid/unavailable 状态;quality 不为 1 或角度缺失只做标记,不改变原成功响应、不要求用户重拍。
- 后台列表在拍摄状态下标注异常;详情增加「拍摄质量与前端校准」;CSV 增加质量状态及参数版本。旧记录不批量补写,仍可查看原有计算备注/原始返回。
- 校准时结合后台原图、前端参数/观测及接口质量结果分析,不将客户端自报当作可信质量结论;本轮不引入自动学习或自动修改线上参数。
## PSD 来源
`tools/export_fourth_feedback_assets.py` 从原 PSD 第 9 页隐藏原扫描效果图层 `9/2/2`,保留原人脸、圆角边框、文字及装饰图标;生成 `scan-base.webp` 和具有真正 alpha 通道的 `scan-face-mask.png`。不修改原 PSD,不使用 AI 重新绘制人脸。
`design/ui-20261012/scan-motion-manifest.json` 记录原 PSD SHA-256、裁切范围、图层路径、遮罩范围、动画周期、色号及资源 SHA-256。新底图/遮罩只在进入档案/相机后加载,登录首屏不请求扫描素材、完整字体或人脸识别引擎。
## 验证
- `node h5/test/customer-feedback-fourth.js`:本地角度/光线/距离/多脸、稳定时长/帧数/漏检/漂移、关注维度/并列/缺失、历史皱纹快照不回写、后台诊断字段清理。
- `node h5/test/customer-feedback-fourth.mjs`:隔离服务器和模拟上游;quality=3 仍成功保存,仅后台标记;后台/CSV/历史报告不回写;游客登录及状态;五种屏宽;快速成功响应等待实际动画一轮。
- 第三轮专项回归:PSD 原文/字体、弹窗、三款产品、装饰图标/键盘、取消/迟到响应/失败恢复及六种等待视口;新动效替代原静态图断言。
- 第二轮、原客户反馈浏览器回归,以及报告持久化/账号隔离/模拟微信回调均通过;推荐规则 126 个用例、原算法 86 条断言、请求超时测试通过。
- 登录性能:150ms 延迟、约 2Mbps 下载及 4 倍 CPU 降速下最后一次冷启动约 1.67 秒,资源 267784 字节;未将识别引擎或扫描图放到首屏。
- 使用本地真实模型对 C3_180、C3_-135、C3_135 三张样例进行推理,当前收紧门限均通过(yaw 约 4.28°/-44.77°/42.59°)。这不是对真实手机拍摄合格率的保证。
- `node h5/test/capture-quality-browser.mjs`:真实识别引擎和原始模型,使用保持长宽比、居中后的三视角样例模拟视频流,实际自动拍摄三张并复验 JPEG;正脸不能冒充侧脸、反方向侧脸不能直接推进,诊断对应正确视角,相机成功后释放。不是手动触发快门,也不是模拟识别结果。
全部写入测试仅发生在独立临时数据目录,上游测肤以本地样例替代;不调用收费 Face++,不修改生产账号、照片、报告或配置。真实手机微信/相机仍需用户最终验收。
## 生产部署及只读验收
- 功能提交:`92a3965b7d637f19ec3d31389f142447339ff2a6`(`feat(h5): apply fourth feedback and tighten local capture validation`)。
- 服务器:`ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`;入口:<https://1me.xajuzi.com/state/>。部署前服务器工作区干净、HEAD 与 origin/main 均为 `e53c809`;通过 Git bundle 快进更新,不代替用户 push、不覆盖服务器私有配置或已有用户数据。
- 更新后重启 `juzi-h5.service`,让服务端评分展示模块、质量诊断模块及前端同版。服务 active/running,`NRestarts=0`,健康接口 `ok:true`;检查时最近 10 分钟错误级日志为 0。
- 公网首页、app/capture-quality/head-pose/report-ui 四个脚本、CSS、两份扫描素材全部 200;逐文件 SHA-256 与本地一致,均为 `Cache-Control: no-cache`。
- 公网未登录报告、后台页面及统计接口均 401;私有身份文件、server.js 均 404;微信配置仍启用,不修改微信凭据或流程。
- 公网真实模型的自动三连拍测试通过:三个实际合格视角自动抓拍、最终 JPEG 本地复验、实际识别到的正脸/错误方向不能冒充目标侧脸、正确诊断归属、报告后释放摄像头;登录与测肤响应仅浏览器内拦截,不产生生产账号或报告、不调用收费测肤。
- 公网第三轮专项串行复验通过:五种屏宽的弹窗断行/产品版式、三款产品、扫描动效与成功进入报告、六种等待视口、装饰图标、取消/迟到响应/失败恢复及字体/扫描图失败降级;无页面 JS 异常。已检查公网首页、等待画面及产品截图。
- 公网第二轮回归串行复验通过:首页口号/Logo 比例、实际 PSD 字体、首屏不加载完整字体和识别引擎、全屏相机、三种圆角轮廓/五官辅助线、五种宽度无溢出;无页面 JS 异常。
- 公网报告交互串行复验通过:三个维度独立滑动/键盘切换、垂直滚动不误切换、图片放大、七张检测图、三档产品排版;皱纹正文显示指定结论、不再包含分区技术附文。无页面 JS 异常。
- 同时启动多套冷浏览器时曾出现字体/资源下载超时;串行重试自动拍摄流程通过。字体仍按原 PSD 使用原始 MiSans,并不将此网络压力测试描述为真实手机合格率保证。
@@ -1,109 +0,0 @@
# 微信登录接入与公网部署说明
更新:2026-10-12。当前环境为 Windows 宿主机 + 内网 WSL。
线上状态补充:`https://1me.xajuzi.com/state/` 已部署并配置真实微信凭据,服务器检查记录见 `线上微信登录部署记录-2026-10-11.md`。2026-10-12 用户已确认手机微信登录成功,服务端亦记录成功回调。下文的内网缺配置说明针对本机开发环境。
2026-10-12 白名单复测已通过,基础凭据有效。最新修正和真机验证步骤见[微信登录联调记录](微信登录联调-2026-10-12.md)。已有本机用户可从「我的报告」→「切换登录方式」进入微信登录;微信会话失效不会自动恢复为本机账号,两个账号的报告不自动合并。
## 本机开发环境限制(不代表线上状态)
本机未配置生产用 `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++ 个人信息与隐私保护政策」(包含儿童相关章节)。本次未发现独立的品牌方用户协议文件,未凭空编写法律条款;正式发布前请业务/法务确认现有政策是否覆盖品牌方的账号关联、报告存储、保存期限和删除渠道。
-60
View File
@@ -1,60 +0,0 @@
# 微信登录联调:2026-10-12
站点:`https://1me.xajuzi.com/state/`;服务器:`ubuntu@1me.xajuzi.com`。
## 后续真机确认与体验优化
- 2026-10-12 用户已在手机微信内通过「切换登录方式」完成真实微信登录;生产服务 10:40:31 记录 `login_success`。下文“待真机验证”是此前预检时点的记录,不再代表当前登录状态。跨手机读取仍只有隔离测试覆盖,未声称用户已做跨手机实测。
- 新增「登录成功」弹框,说明当前使用微信或本机浏览器;首页右上角、我的报告顶部持续展示登录方式,并可点击切换。恢复有效会话不重复弹框;错误回调、丢失 Cookie 不显示成功。
- 登录加载慢的实测原因、优化及验证命令见[登录反馈与加载优化](登录反馈与加载优化-2026-10-12.md)。
## 白名单与凭据
- 用户再次确认已将服务器出口 IP `49.233.222.47` 加入公众号 IP 白名单。
- 从生产服务正在运行的进程环境读取凭据,在服务器调用微信 `cgi-bin/stable_token`,使用 `force_refresh:false`,未强制刷新已有令牌。
- 返回有效 `access_token`,未返回 `40164`;复测剩余有效时间为 7168 秒。已确认该配置的 AppID 与 `wx645d9a7573f1fe9a` 一致,AppID/AppSecret 校验通过。
- 密钥继续留在 root 私有文件 `/etc/juzi/wechat.env`(600);服务监听 `127.0.0.1:8080`,站点地址包含 `/state/`。没有将密钥或令牌写入代码、日志、文档或前端。
- 基础接口令牌成功不等于真实用户网页授权成功;后者仍要验证公众号网页授权权限、网页授权域名以及真实微信客户端回调。
## 本轮修正
1. 「我的报告」增加「切换登录方式」,复用现有登录页。已有本机用户可以进入微信登录;重新勾选协议后才发起授权。只切换所选账号,不自动合并、迁移或删除报告;返回可继续原会话。
2. 本地只记录最近一次有效登录的方式(`juzi.auth.kind.v1`),不存 OpenID 或微信令牌。微信会话失效后,不能用遗留本机随机凭据自动登录另一个账号;需显式重新选择登录方式。同一微信重新登录仍对应同一服务端账号。
3. 微信返回错误或返回后 Cookie 未保留时,保持登录页并说明原因,不允许用本机自动恢复掩盖失败。处理后移除 URL 的一次性登录结果参数,避免刷新后反复显示旧错误。
4. 服务端拒绝微信响应中的无效 OpenID、异常 HTTP 状态等错误响应;网络失败、平台失败、state 校验失败均不签发会话。
5. 增加 `[auth/wechat]` 运行事件:`callback_rejected`、`exchange_failed`、`login_success`。仅记录错误种类、微信数值错误码、HTTP 状态和是否新账号;不记录 code/state、Cookie、OpenID、密钥或令牌。
## 自动验证
```bash
node h5/test/accounts.js
node h5/test/wechat-browser.mjs
node h5/test/report-persistence.mjs
node h5/test/recommendation.js
node h5/test/analyze-timeout.js
H5_BASE_URL=https://1me.xajuzi.com/state/ node h5/test/wechat-production.mjs
```
- 账号测试覆盖协议、同源校验、state 绑定/一次性使用、跨账号隔离、账号持久化;新增无效 code、空响应、非字符串 OpenID、HTTP 500 和网络错误均拒绝登录的验证。
- 真实 HTTPS + `/state/` 浏览器测试仅模拟微信上游,覆盖本机→微信→本机显式切换、原报告保留、同一微信跨两个独立浏览器读取同一报告、另一微信无法读取、Cookie 丢失不串号、失败提示不被本机自动恢复掩盖。
- 报告保存与回看、前后台一致性、126 个推荐用例及检测超时回归通过;不调用收费 Face++。
- 公网预检脚本只使用刻意无效的 code,验证授权 URL/绑定 Cookie、真实微信拒绝无效换码、state 防重放、同源与协议校验、匿名报告拒绝及后台保护;不创建微信身份,不表示真人授权成功。
- 部署后公网预检复测通过,新版 HTML/脚本已实际提供;本地和线上代码校验一致,服务与 nginx 均正常。生产日志中的 `40029` 来自上述刻意无效 code 的负向测试,并非一次真人登录失败;尚未收到本轮真人授权成功的回调。
## 真实微信验收与排查
目前尚不能将模拟授权和基础凭据通过视为真人登录已完成。服务器与无头浏览器不能替用户产生真实微信授权 code,也不在生产环境伪造微信身份。
1. 手机微信内打开 `https://1me.xajuzi.com/state/`,不要选择「在浏览器打开」。
2. 若已有本机登录,进入「我的报告」→「切换登录方式」;勾选协议,点击「微信登录」。
3. 登录后进入「我的报告」,身份提示应为「同一微信账号可跨手机查看」。首次使用微信身份时列表可能为空:本机账号历史报告不会自动合并。
4. 同一微信重新登录或换另一台手机查看,账号和已保存微信报告应一致;无需为了验证登录再次调用收费检测。
5. 如微信自身页面提示域名或 scope 权限错误,请核对对应 AppID 公众号的「网页授权域名」是否为 `1me.xajuzi.com`、是否有网页授权权限;这些设置不能由域名校验文件存在或基础接口令牌通过来推断。
服务端排查命令:
```bash
sudo journalctl -u juzi-h5.service --since '10 minutes ago' --no-pager | grep -F '[auth/wechat]'
```
只需反馈页面是否进入首页/报告列表,或错误页面截图。不要传授权 code、Cookie、OpenID、AppSecret 或接口令牌。
-11
View File
@@ -1,11 +0,0 @@
# 微信退出登录
- 首页与「我的报告」的状态区,仅微信已登录时显示「退出登录」。游客模式不显示,不恢复旧的「切换登录方式」按钮。
- 点击使用系统确认框提示:确认退出微信登录?历史报告将保留,重新微信登录后可查看。取消不调用退出接口。
- 确认后调用现有 `api/auth/logout`,撤销当前服务端会话和 Cookie;成功才清除前端登录状态并回到入口页。失败提示错误,保留当前页面/身份并允许重试;请求期间禁用退出按钮,防止重复提交。
- 不删除账号、报告快照或微信偏好缓存。退出后重新登录同一微信,仍可查看原有历史报告。
- 退出时清空历史列表并作废在途历史请求,限制旧报告的返回导航;旧微信请求迟到也不能在游客身份下打开报告。
验证:`node h5/test/wechat-browser.mjs`(模拟微信、真实 HTTPS Cookie)覆盖取消、接口失败、确认退出、服务端会话撤销、返回键、迟到报告、游客不显示退出及重新微信登录后快照文件字节不变。`node h5/test/guest-privacy.mjs`、`node h5/test/report-persistence.mjs` 回归游客与历史报告。
用户已确认与原始肌龄显示、鸿蒙滚轮兼容一起发版。发布沿用 Git bundle 快进同步和服务重启,不代用户推送 origin,不删除历史报告。微信退出流程使用隔离模拟账号验证;线上不操作真实微信账号、报告或付费接口。
@@ -1,64 +0,0 @@
# 报告布局与跟手交互调整
> 综合评分布局已按后续要求调整为标题和分数整体在圈内居中;年龄标签与数字间距为 25px。最新实现与验证见《评分圈内居中与正脸语音修复-2026-10-12.md》。本文件其余跟手交互、JPG 优化与历史发布记录保留。
## 本次范围
1. 综合评分:标题移到黄色圆环外正上方,与「生物可视年龄」同高;分数数字本身水平、垂直居中,「分」独立放在数字右侧,不把分数挤偏。
2. 护理建议:标题左对齐,其他文案不变。
3. 检测等待:回退实拍背景,使用原 PSD 白色人头及黄色扫描动画,不出现用户照片。保留约 1 秒一轮、成功至少播放一轮、取消/失败立即退出,以及素材失败时的文字状态和取消入口。
4. 拍摄震动:复核现有功能。前端判断距离、居中、角度、光线等通过、进入「保持不动」时请求 `[70,40,70]` 毫秒短振;同一步抖动重试最多每两秒提醒一次,自动快门不重复震动。不支持、返回 false 或抛异常都静默跳过,不阻碍拍摄。是否实际震动仍取决于手机和浏览器,自动化不代替物理真机验证。
5. 报告三组页签:与「日常肤质」共用轻量滑动控制器。拖动时内容随手指平移,松手按距离/速度吸附;支持短拖回弹、轻扫、首尾阻力、系统取消和旋转屏幕。保持点按/键盘切换、上下滚动、图片点按放大;拖动不误触放大。各卡片独立,容器高度跟随当前内容,非当前页签从辅助阅读/焦点导航中排除。
6. JPG 优化:只转换在实际展示背景上可明显减小体积的三张产品图,原始 WebP、PSD 和原导出清单完整保留。背景和扫描底图仍用更小的 WebP;透明 logo、图标和蒙版保留 PNG。送检照片原本就是 JPEG,本次不二次压缩、不改变检测输入。
## 资源体积
| 产品 | 原始 WebP | 网页使用 JPG | JPG 质量 |
| --- | ---: | ---: | ---: |
| 25+ | 276,778 B | 63,959 B | 90 |
| 35+ | 267,094 B | 66,077 B | 90 |
| 50+ | 331,924 B | 153,787 B | 96 |
| 合计 | 875,796 B | 283,823 B | 减少 67.6% |
三张图保持 504×503,白色产品卡底色合成,渐进式 JPEG、4:4:4 色度采样,PSNR 均不低于 40dB。页面只加载实际推荐的一款。构建脚本 `tools/optimize_delivery_images.py` 可重复生成;原图/新图的 SHA-256、体积、尺寸与参数记录于 `design/ui-20261012/delivery-optimization-20261012.json`。
## 验证
本地 8080 服务运行后执行:
```bash
node h5/test/report-touch-layout.mjs
node h5/test/scan-placeholder.mjs
node h5/test/profile-interaction.mjs
node h5/test/customer-feedback.mjs
node h5/test/customer-feedback-second.js
node h5/test/customer-feedback-second.mjs
node h5/test/customer-feedback-third.mjs
node h5/test/customer-feedback-fourth.js
node h5/test/customer-feedback-fourth.mjs
node h5/test/capture-quality-browser.mjs
node h5/test/report-persistence.mjs
node h5/test/login-performance.mjs
node h5/test/recommendation.js
node h5/test/regression.js
node h5/test/customer-feedback.js
node h5/test/profile-store.js
node h5/test/analyze-timeout.js
```
以上均通过。覆盖五种报告宽度/六种扫描视口、真实移动端触摸拖动中位移、三组吸附与高度、纵向滚动、放大/键盘、原稿素材哈希、白色人头、扫描完整循环和失败降级、实际本地人脸模型自动三连拍、账号隔离/历史报告/前后台一致性,以及评分和推荐规则回归。
慢网性能模拟:150ms 延迟、约 2Mbps 下载、4 倍 CPU 降速,测试冷启动登录约 1.68 秒,首屏资源 271,106 B;字体、人脸识别、产品和扫描图仍不竞争登录首屏。这是本地模拟测量,不等同于所有真机的公网耗时。
本次未修改拍摄合格阈值、评分算法、推荐规则、报告文案、登录或保存逻辑。未追踪的 `new_feedback/` 保持原样,不纳入本次提交。
发布目标为 `ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`,服务 `juzi-h5.service`。沿用 Git bundle 快进同步,不代用户推送 origin,不更改服务器环境配置或历史数据;上线后核对静态文件哈希、服务健康和匿名访问保护,并通过公网执行只读模拟账号浏览器测试。
## 线上验收(2026-10-12)
- 功能提交 `63c9e06`,从服务器基线 `69dc996` 快进发布,已重启服务。`active/running`,退出码 0、自动重启次数 0,本机及公网健康检查均通过。
- 公网首页、app/swipe-track/report-ui/profile-store/capture-quality 脚本、最新 CSS、三张 JPG、扫描底图与蒙版,共 12 份静态资源均为 200,SHA-256 与本地一致,保持 `Cache-Control: no-cache`;JPG 正确返回 `image/jpeg`。
- 公网匿名会话未登录且 `no-store`;报告列表、后台页面/统计返回 401,账号私有数据及服务端源码/测试入口返回 404。
- 公网 `report-touch-layout.mjs`、`scan-placeholder.mjs`、`profile-interaction.mjs` 全部通过;覆盖此次报告布局、三组真实触摸跟手/吸附/取消/边界/上下滚动/图片放大,以及白色人头扫描完整周期、失败/取消/迟到响应和基础信息记忆/隔离。没有页面 JS 异常,不创建线上账号/报告,不调用付费检测。
- 新报告专项脚本首次使用默认 `load` 导航与 30 秒预算,在公网冷加载字体/测试素材时超时。测试改为与现有公网用例一致的 60 秒预算及 `domcontentloaded` 导航,仍等待真实报告渲染与字体加载后执行原有断言,复验通过;不改运行时代码和界面行为。
- 已检查线上报告、滑动中状态和白色人头扫描截图。震动是否实际发生仍需支持该能力的手机真机确认。
@@ -1,23 +0,0 @@
# 报告等待页实拍背景
> 此文档记录上一版实现,已按后续用户要求回退:等待页不再展示用户照片,仅保留 PSD 白色人头和扫描动画。当前验证脚本为 `h5/test/scan-placeholder.mjs`。
原扫描页直接展示 PSD 的白色人脸占位。上一版改为在原 PSD 人脸蒙版内叠加本次正脸照片,扫描线置于照片上方;原素材不重绘,框、检测中文字、装饰图标与取消入口不变。
- 首张合格正脸就预解码,三张拍完使用同一张正脸,不使用最后一张侧脸或其他报告照片。
- 与拍摄预览一样居中、等比 `cover` 铺满,不拉伸照片。前置实时拍摄保留当时的预览镜像;后置/相册/系统相机文件不额外镜像。镜像只作用于 CSS,不改变送检 JPEG。
- 已有“一次完整扫描才进成功报告”保持不变;照片延迟解码时重启扫描,错误/取消不等待动画。
- 成功、失败、取消、页面隐藏或重新拍摄时清理等待页图片引用,不残留上一轮人脸。照片不新增缓存/上传/持久化。
- 素材或蒙版加载失败时降级为实拍背景、检测中文字和取消入口;照片解码失败使用深色背景,不露出白色占位。
- 不修改拍摄约束、评分、肌龄、推荐规则或报告保存逻辑。
当前回退版验证命令(本地服务需运行于 8080):
```bash
node h5/test/scan-placeholder.mjs
node h5/test/capture-quality-browser.mjs
node h5/test/customer-feedback-third.mjs
node h5/test/customer-feedback-fourth.mjs
```
测试只使用模拟账号、拦截分析响应,不创建线上记录、不调用付费检测。当前脚本验证白色人头、不展示用户照片、六种视口、扫描完整循环、成功/失败/取消清理、迟到响应及素材失败降级。
@@ -1,16 +0,0 @@
# 报告页滑动防冲突
仅优化报告详情卡的手势,不修改报告数据、算法或基础信息页的滑动参数。
- 图片区域可横向跟手切换;说明文字不触发横滑,页签仍可点击或键盘切换。
- 当前试用横向优先:移动超过 12px 且横向位移大于纵向的 2/3 即进入横滑;只有纵向位移达到横向的 1.5 倍时才锁定竖滑。一次手势锁定后不重新判方向。之前上线的竖向优先版本要求横向大于纵向的 1.5 倍才横滑。
- 修正浏览器抢占:仅改方向比例时,`touch-action: pan-y` 仍可能让浏览器提前滚动并发送 `pointercancel`。现在仅报告详情卡启用非被动 `touchmove`,与 Pointer Events 共用同一方向锁;图片区域单指横滑时取消原生滚动,竖滑和文字区域不拦截。不通过 `pointermove.preventDefault()` 或指针捕获来假定原生滚动已被阻止。
- 横滑过程中冻结卡片当前高度,包括图片/字体延迟加载导致的尺寸更新;松手或取消后再恢复当前页签高度,并沿用平滑高度过渡。
- 首尾保留阻尼反馈,但回弹位移最大为 16 CSS px,不允许拉出大片空白。
- 保留浏览器原生纵向滚动、图片点击放大、取消复位与无障碍页签行为。不尝试拦截微信系统返回手势。
验证:`node h5/test/report-touch-layout.mjs` 检查真实移动触摸横滑、斜滑、文字区不切页、图片与文字区竖向滚动、拖动期间高度不变、边缘位移上限和原有布局/交互;`node h5/test/profile-interaction.mjs` 回归共用滑动组件的基础信息页。
新增回归覆盖横移 60px/纵移 75px、横移 80px/纵移 90px 的六段真实触摸路径(之前均会触发 `pointercancel` 并竖滚)。现在每组三张报告卡都检查松手前跟手位移、无浏览器取消、正确切页,以及拖动中/松手后竖向位置均不变。本地报告、基础信息交互和算法 86 条断言均通过;不调用付费检测或写入报告。
之前的竖向优先版本已发布;当前横向优先版本已通过本地报告交互测试,按用户要求发版。发布沿用 Git bundle 快进同步至 `/home/ubuntu/juzi`,重启 `juzi-h5.service`,再经公网运行同一报告交互测试并检查服务健康及静态资源一致性。不代用户推送 origin,不包含未追踪的 `new_feedback/`。最终手机微信体验仍需真机复验。
@@ -1,11 +0,0 @@
# 报告顶部评分与年龄排版
- 分数数字与「分」组成同行整体,下面显示「综合评分」,间距 0 CSS px。两行共用水平中心线,整个分组在圆圈内水平、垂直居中。
- 「生物可视年龄」标题与年龄数字间距 0 CSS px,作为整体与左侧圆圈竖向居中对齐。
- 保留原文字、字号、数据和算法,不更改其他页面或服务器配置。
## 验证与发布
`node h5/test/report-touch-layout.mjs` 验证五种屏宽、0/75/82/100/缺失分数:单位计入分数组宽度、标题在数字下方、零间距、分组居中及年龄对齐;同时回归报告跟手切换等既有交互。测试使用模拟数据,不写报告、不调用付费检测。
本地验证通过。发布沿用 Git bundle 快进同步至 `/home/ubuntu/juzi` 并重启 `juzi-h5.service`,发布后经公网重跑上述测试并核对静态资源与健康检查。不代用户推送 origin,不包含未追踪的 `new_feedback/`。
@@ -1,41 +0,0 @@
# 拍摄约束放宽与标题更新
依据用户真实手机反馈:上一轮拍摄过于费劲,适度放宽前端门限,页面名称改为 `1'me肌肤状态检测`。此次不修改设计素材、评分、肌龄、推荐规则、微信登录流程或历史报告。
## 参数对照
参数版本由 `2026-10-12-fourth-v1` 升为 `2026-10-12-fourth-v2`;新报告后台保存新版本与配置快照,已有记录不回写。
| 项目 | 上一轮 v1 | 本次 v2 |
| --- | --- | --- |
| 人脸置信度 | ≥0.5 | ≥0.4 |
| 人脸框高占原帧 | 34%~64% | 30%~68% |
| 水平偏离屏幕中心 | ≤12% 屏宽 | ≤16% 屏宽 |
| 检测框边缘余量 | ≥2% 原帧 | ≥1% 原帧 |
| 正脸 yaw/pitch | ≤10°/12° | ≤15°/18° |
| 侧脸幅度/pitch | 35°~65°/≤15° | 30°~70°/≤20° |
| 歪头 roll | ≤10° | ≤15° |
| 脸部平均亮度 | 75~225 | 65~235 |
| 稳定时长/检测帧数 | ≥650ms/≥3 帧 | ≥450ms/≥2 帧 |
| yaw/pitch 漂移 | ≤5° | ≤8° |
| 中心 x/y 漂移 | ≤原帧 3.5% | ≤原帧 5.5% |
| 框高占比变化 | ≤4.5 个百分点 | ≤6.5 个百分点 |
仍要求单人出镜、完整入镜、正确视角、基本距离/光线;最终 JPEG 必须通过同一套本地复验。没有删除质量检查、绕过检测、增加服务端质量拦截或网络往返。漏检/识别异常及超过 2 秒的检测间隔仍打断累计。已有模型不可用降级路径保持不变,后台明确标记未校验。
最低稳定等待减少 200ms;慢设备从至少三次合格观察减为两次,减少持续保持姿势的难度。实际速度仍取决于手机模型推理耗时,不能保证所有机型和环境的检测合格率。
## 标题
`h5/index.html` 的 HTML title、Open Graph 分享标题及页面描述统一改为 `1'me肌肤状态检测`。首页 PSD 原组合图已经是「肌肤状态检测」,无需改图。
## 验证与发布
本地已通过:
- 参数边界:上一版偏头/俯仰/偏位/亮度/轻微漂移等拒绝样例现在通过,多人/错误视角/裁切/大幅移动仍拒绝;450ms 两帧准确触发,短于 450ms 不触发,漏检/超时间隔重置。
- 真实模型自动三连拍及最终 JPEG 本地复验,正脸不能冒充侧脸、错误方向不能推进,诊断照片归属正确,成功后释放摄像头。
- 隔离服务器后台诊断保存 v2 配置快照;页面与分享标题正确;quality=3 不阻断报告,游客状态、历史快照、五种屏宽及实际一轮扫描动画通过。
- 报告持久化、后台/H5/CSV 一致、账号隔离、皱纹原文;账号/OAuth 单测;原算法 86 条及推荐规则 126 用例;请求超时与震动安全回归。
部署目标:`ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`,部署基线 `3f165bf`,通过 Git bundle 快进同步、不代用户 push。重启 `juzi-h5.service` 以保存新版后端参数快照。生产验证仅 GET 请求及浏览器内存拦截,不创建线上账号/报告,不调用收费 Face++。
@@ -1,24 +0,0 @@
# 拍摄角度不合格震动提醒
按用户确认的规则实现,纳入 2026-10-13 相机与首页更新发版。
- 实时检测确认单人、清晰度、距离与居中等前置条件通过,但角度不合格连续约 1 秒后,调用一次 30ms 轻震。
- 持续角度不合格时,相邻提醒至少间隔 4 秒;不使用独立定时器,只有收到新检测结果才可能提醒。
- 合格、无人脸、其他质量问题或检测失败立即取消震动并重置连续计时;漏帧也中断计时。检测结果间隔超过 2 秒会重新累计,避免推理卡顿被误认为持续不合格。
- 自动拍摄、手动快门和拍摄完成均不再震动。
- 拍摄锁、摄像头切换/未就绪、离开拍照页及切后台禁止提醒。停止检测、步骤重置或开始拍摄时取消尚未结束的震动。
- 前后提示保持 4 秒限频,不因角度短暂合格、镜头切换或步骤重置绕过冷却。
- 不支持接口、接口拒绝或抛出错误时静默忽略,不影响原有文字、语音和自动拍摄。
没有改变拍摄角度、距离、亮度、稳定时间或评分推荐算法。不是所有手机都能产生物理震动,微信/鸿蒙需真机复验,iOS 当前按无震动降级。
验证命令:
```sh
node h5/test/customer-feedback-second.js
node h5/test/customer-feedback-fourth.js
node h5/test/camera-flip-browser.mjs
node h5/test/capture-quality-browser.mjs
```
测试涵盖定时边界、持续限频、合格取消、无人脸、非角度问题、拍摄/切换/后台隔离、不支持/拒绝安全降级,以及相机翻转和真实本地模型三连拍回归。浏览器测试使用模拟相机和拦截的身份/报告接口,不调用付费检测、不写真实账号或报告。
@@ -1,34 +0,0 @@
# 游客不留存与弹窗护理间距调整
## 发版范围
本次已完成本地开发、截图与用户确认,按要求提交和部署。发布沿用 Git bundle 快进同步至 `/home/ubuntu/juzi` 并重启 `juzi-h5.service`;不代用户推送 origin,不删除既有服务器历史数据或更改微信配置。发布后校验静态资源哈希、服务健康、免登录入口、协议同意前后临时会话边界和游客空历史;不调用线上付费检测或写入真实报告。
- 欢迎弹窗保留完整句子「我已阅读并同意相关隐私协议」,仅「隐私协议」四字加粗并下划线;「相关」恢复为普通文字,点击协议不勾选同意。
- 报告护理建议标题的下方间距由 18u 减为 9u(375px 屏宽对应 18px→9px),仍左对齐,不影响其他标题。
- 仅微信登录保留个人偏好和历史报告。微信现有账号、最近 5 份完整报告、跨手机查询、后台记录与原始结果留存不变。
- 游客入口改为「免登录体验」:不要求登录页勾选协议,不发起登录请求、不弹登录成功,直接进入首页。开始检测时仍须在欢迎弹窗明确同意隐私协议,之后才建立后台检测所需的临时会话。首页/报告列表的「切换登录」按钮删除,状态改为不可点击的「游客模式」/「微信已登录」。微信登录保留在原入口页,以及游客历史页的「微信登录,保存报告」入口。
- 游客使用内存中临时身份和非持久 Cookie,不落盘账号/会话,不再发送或保存可恢复的游客凭据。浏览器旧游客身份、基础信息和早期本地报告缓存清除;不清空其他应用或微信的缓存。
- 游客基础信息只在当前页面操作中使用,例如拍摄失败返回可继续重拍;不写 localStorage,刷新/新游客登录后重新填写。游客报告仅供本次查看;「我的报告」显示不保存提示,不请求历史列表、不展示旧游客报告。
- 服务端同样限制:游客成功/失败均不新增 records.jsonl、照片、原始结果和完整报告快照;检测和评分在内存中正常进行。检测响应设为 no-store,游客不出现「保存失败」误提示。该规则指本项目不留存,不代表上游检测供应商的数据政策发生变化。
- 已有服务器游客历史数据不自动删除(避免未经确认批量清理);旧持久游客凭据不能恢复身份或读取历史。后续若需清理存量数据,应另行确认范围与备份。
## 验证
使用隔离临时目录、固定图片/上游响应与模拟微信;不操作线上账号/数据,不调用付费检测。
```bash
H5_ARTIFACT_DIR=/tmp/juzi-guest-privacy-20261013 node h5/test/guest-privacy.mjs
node h5/test/accounts.js
node h5/test/profile-store.js
node h5/test/profile-interaction.mjs
node h5/test/report-persistence.mjs
node h5/test/wechat-browser.mjs
node h5/test/customer-feedback-fourth.mjs
node h5/test/login-performance.mjs
node h5/test/report-touch-layout.mjs
```
新增端到端测试比对游客成功/失败前后的整个临时数据目录字节,确保无身份、照片、档案、报告、检测原文或后台记录写入;同一服务随后切换微信,验证报告/照片/后台记录正常保存。既有测试更新为仅微信持久化,保留跨设备、历史快照不可变、账号隔离和基础信息/拍照/报告交互回归。
截图:guest-entry.png、guest-home.png、welcome-privacy.png、care-spacing.png、guest-history.png(均为本地界面,报告内容为固定样例)。最新版可运行 `H5_ARTIFACT_DIR=/tmp/juzi-guest-no-login-20261013 node h5/test/guest-privacy.mjs` 生成。
@@ -1,46 +0,0 @@
# 登录反馈与加载优化(2026-10-12)
## 体验变化
- 显式本机登录、微信授权成功且会话确认后,显示「登录成功」弹框,说明登录方式和报告访问范围。
- 首页右上角和「我的报告」顶部显示「微信已登录」或「本机浏览器已登录」;标识可点击切换。依据服务端会话的 `user.kind`,不根据浏览器是否处于微信来猜测。
- 刷新后恢复有效会话不重复弹框。授权失败、Cookie 丢失不会显示成功;不合并账号、不删除缓存身份或历史报告。
- 弹框支持确认按钮、Esc、键盘焦点约束,关闭后恢复页面交互。
## 慢的原因与处理
优化前,在开发机浏览器对公网页面的一次无缓存测量:HTML 首字节约 244 ms,登录约 5510 ms 可操作;同步排在应用前的 face-api.js 853487 字节、下载约 4319 ms。两份完整字体分别 4858624 和 5034212 字节,下载约 14.5/15.6 秒。额外还预加载了已不使用的旧首页背景(约 590 KB)。认证状态接口独立 curl 测量约 431 ms,不能将本次首屏等待主要归因为微信接口;手机网络、DNS/TLS 和真实授权往返仍会影响实际时间。
处理:
1. 人脸引擎改为进入拍照、实际可用相机或系统相机降级时才请求;加载失败可重试,20 秒超时后保留手动兜底。模型/自动抓拍算法不变。
2. 登录、首页、报告列表使用系统字体;进入档案/拍照/报告时再注册原始 MiSans 字体。字体原文件保持不变。官方许可不允许改编或二次开发,因此没有对子集化作授权推断。[官方许可](https://hyperos.mi.com/font/zh/download/)。
3. 保留 PSD 原导出和 JPEG,新增 WebP 分发背景(同分辨率),移除旧背景预加载,优先加载登录背景。生成方式:`python tools/prepare_h5_assets.py`。
4. Node 静态资源增加 gzip 和 ETag/304,继续 `Cache-Control: no-cache` 及时校验新版本;仅压缩静态公共文本,不缓存/压缩账号、报告等私有 API 响应。未改 nginx 后台保护配置。
5. 微信登录去掉多余的配置查询往返,直接请求受协议及同源校验保护的授权接口;禁用环境仍由服务端明确拒绝。仅登录鉴权请求增加 12 秒超时,失败后不清除身份凭据;不缩短含照片报告的下载等待时间。
## 验证
```bash
H5_ARTIFACT_DIR=/tmp/juzi-login-20261012 node h5/test/login-performance.mjs
node h5/test/wechat-browser.mjs
node h5/test/accounts.js
node h5/test/report-persistence.mjs
node h5/test/recommendation.js
node h5/test/analyze-timeout.js
H5_ARTIFACT_DIR=/tmp/juzi-login-ui-20261012 node h5/test/ui-20261009.mjs
node h5/test/browser-failures.mjs
node h5/test/e2e-browser.mjs
```
隔离性能测试:150 ms 网络延迟、约 2 Mbps 下载、CPU 四倍降速,冷登录可操作约 1598 ms,静态资源编码后共 259547 字节;登录、首页不请求完整字体、人脸引擎或模型。另验证 gzip 解码一致、304、拒绝 `gzip;q=0`、私有 API `no-store`、超时保留身份、320/375/390/480 宽度标识不遮挡文案。拍照时引擎失败重试后,真实模型能返回 68 点人脸特征。
以上是可重复的开发机模拟结果,不等于每部手机的耗时保证,也不能直接与未限速的公网测量作同条件性能比例比较。测试不调用收费 Face++。
## 公网部署后复测
代码 `d2931a4` 已在本机和生产同步,生产 `juzi-h5` 与 nginx 均正常。部署前确认近 180 秒无进行中的检测;仅更新跟踪代码,未迁移、清理或覆盖 `h5/data`,没有改变微信凭据或域名设置。
同一开发机、无浏览器缓存的公网复测:HTML 首字节约 222 ms,登录可操作约 311 ms,资源编码后共 259678 字节;未请求完整字体或人脸引擎。随后刷新页面,资源网络传输约 7523 字节(其余走校验缓存)。这是一次观测值,不能保证所有手机达到该时间。
线上 gzip 与 ETag/304 已验证;健康、登录配置接口正常,匿名报告与后台均拒绝访问,私有数据目录不可公开读取。复测只读,不创建生产测试账号、报告,也不发起新的微信授权或收费检测。
@@ -1,29 +0,0 @@
# 相机翻转性能优化
本次优化纳入 2026-10-13 相机与首页更新发版。
## 修改范围
- 相机首帧 readyState ≥ 2 且宽高有效后即可显示,检查周期 50ms;去掉原有三轮 300ms 分辨率预热等待。
- 翻转过程中保留上一帧及原来的镜像方向,显示“正在切换摄像头…”。静帧仅保存在内存 Canvas,恢复预览或离开页面后清空,不上传、不持久化。
- 启动/翻转时禁用翻转按钮,拍摄和步骤推进期间拒绝翻转。
- 新镜头失败、首帧等待超时或浏览器明确返回错误的 facingMode 时,尝试恢复原镜头一次;恢复也失败才降级到系统相机。
- 翻转及恢复请求设置 12 秒超时,初次权限询问不设置该超时。首帧单独设置 12 秒超时,不再超时强行认为成功。迟到的流及时停止。
- 检测循环增加代次令牌,旧镜头推理结果不可更新新镜头状态或启动第二条循环;旧推理未结束时不叠加新推理。
- 模型加载回调也校验镜头令牌,避免旧回调覆盖切换状态。
拍摄角度、亮度、尺寸、清晰度、稳住时间、照片编码、评分和推荐规则均未修改。
## 验证
- `node h5/test/camera-flip-browser.mjs`:模拟相机验证首帧显示时延、静帧、重复点击、拍摄锁、失败/忽略 facingMode/超时恢复、旧推理隔离、离开后迟到流释放。
- `node h5/test/capture-quality-browser.mjs`:真实本地模型、三角度自动拍摄、最终 JPEG 复验、语音顺序、摄像头释放通过。
- `node h5/test/login-performance.mjs`:登录轻量加载、相机模型按需加载/失败重试等通过。
- 无付费检测调用、真实账号和报告写入。
模拟相机对比:原实现首帧后额外等待约 900ms,两轮优化后约 57~91ms(受测试机器调度影响)。不是手机真机性能结论。
## 仍需真机验证
微信 Android、iOS、鸿蒙:连续翻转、后置转前置、翻转时返回/切后台、拒绝相机权限、拍摄中点击翻转。
摄像头硬件/微信浏览器重新启动本身的耗时无法消除;不提供 getSettings().facingMode 的浏览器只能依赖 facingMode ideal 选择,无法保证识别其是否忽略请求。
@@ -1,68 +0,0 @@
# 线上微信登录部署记录
时间:2026-10-11(北京时间)。服务器:`ubuntu@1me.xajuzi.com`,页面:`https://1me.xajuzi.com/state/`。
2026-10-12 最新状态:白名单已生效,生产服务器成功获取微信基础接口令牌,AppID/AppSecret 校验通过;新增账号切换、会话失效防串号和回调诊断,详见[本轮联调记录](微信登录联调-2026-10-12.md)。下文 `40164` 是历史结果,真实微信客户端授权仍待验证。
## 后续更新:已配置真实凭据
用户提供凭据后,已将其写入 `/etc/juzi/wechat.env` 并重启服务。该文件仅 root 可读写(600),目录为 700;临时凭据文件已移除,未写入代码库或前端。
- 公网健康检查正常;`/state/api/auth/config` 返回 `wechat: true`。
- 真实登录入口返回微信授权 URL;AppID 与配置匹配,作用域为 `snsapi_base`,回调为 `https://1me.xajuzi.com/state/api/auth/wechat/callback`。
- OAuth 绑定 Cookie 确认为 HttpOnly、Secure、SameSite=Lax,路径 `/state/`;回调无效 code 后返回登录错误,重复 state 被拒绝,未错误发放登录会话。
- 微信网页授权换码接口使用诊断用无效 code 返回 `40029 invalid code`,未返回 IP 白名单错误。这只验证端点连通和错误处理,不能证明 AppSecret 正确或真实授权成功(无效 Secret 对照也返回相同错误)。
- 微信基础接口 `/cgi-bin/stable_token` 返回 `40164`,服务器出口 IP `49.233.222.47` 不在公众号 IP 白名单。须由公众号管理员加入后,才能完成这项基础凭据校验;不能直接把此错误认定为网页授权登录必然失败。
- 自动浏览器能够从真实页面发起微信跳转,但无法取得真实微信客户端授权 code,因此没有伪造生产微信身份或宣称真人登录已通过。
剩余验证:公众号管理员添加基础接口 IP 白名单;在真实微信内完成一次授权,确认权限与网页授权域名,并检查首页和报告列表。非登录功能的真实闭环结果见 `线上闭环测试-2026-10-11.md`。
### 用户确认加入白名单后的复测
2026-10-11 14:50 UTC,从同一生产服务器间隔复测:`stable_token` 和标准 `cgi-bin/token` 均仍返回 `40164`,提示 `49.233.222.47` 不在白名单。已确认服务器读取的 AppID 与用户提供的 `wx645d9a7573f1fe9a` 一致;未输出密钥或令牌。仍需核对是在该 AppID 对应账号的 **IP 白名单** 中添加并保存,而非网页授权域名/业务域名或其他微信应用的白名单。
网页授权端点返回的 HTML 仅做微信客户端环境判断,并未提供账号权限/域名是否合规的诊断结果;伪造 User-Agent 无法完成真实授权。换码负向测试仍正常,因此上述基础接口错误不能替代真实微信登录的验收结果。
## 已执行
- 确认服务器仓库为 `55b3a45`,包含 `ce8d0ff` 登录和 UI 更新;未覆盖服务器仓库文件。
- 原 Node 进程仍运行旧版本,重启 `juzi-h5.service` 后新账号接口生效。
- 新增 `/etc/systemd/system/juzi-h5.service.d/wechat.conf`,设置实际 HTTPS 站点地址、回环监听、代理信任和私有环境文件加载。
- 初次准备 `/etc/juzi/wechat.env` 时两个微信变量为空;随后已配置真实凭据。目录权限 700、文件 600,均为 root 所有。
- 修改 `/etc/nginx/sites-available/juzi`:为 `/state/api/admin/` 增加 Basic Auth(原先只有 `/api/admin/` 受保护);兼容旧路径,覆盖真实 IP 请求头;请求体上限调整为 20 MB,读取超时调整为 150 秒。
- `nginx -t` 通过后平滑 reload,原证书、管理员密码文件和域名验证文件未改动。
- Node 确认仅监听 `127.0.0.1:8080`。
备份:`/etc/juzi-deploy-backup.3ipdsA/`,含修改前 nginx 配置和 systemd 主服务文件。新增 systemd drop-in 为独立文件,可单独回退;数据目录未移动或删除。
## 初次部署的线上检查(历史结果)
| 检查 | 结果 |
|---|---|
| `/state/`、`/state/api/health` | 200 |
| `/state/api/auth/config` | 200,wechat=false,明确缺配置 |
| 匿名读取报告 | 401 |
| `/state/api/admin/stats`、`/api/admin/stats`、后台页面 | 401 |
| 数据目录、编码斜杠源码路径 | 404 |
| 同站但未同意协议的登录请求 | 400 |
| 跨站登录请求 | 403 |
| 微信登录请求(尚无凭据) | 503,未伪装登录成功 |
| 无效微信回调 | 302,返回 `/state/?login_error=state` |
| 根目录微信验证文件 | 200 |
## 初次部署时的凭据查找记录(现已由用户提供)
查找到的是 `MP_verify_kpx234XimQGtFPo6.txt`,只有 16 字符校验串;本地与服务器相关目录均未找到同名 `.md`。它用于域名验证,不包含 AppID/AppSecret,也不能用于换取微信用户身份。
在服务器运行 `sudoedit /etc/juzi/wechat.env`,填写对应公众号凭据:
```ini
WECHAT_APP_ID=公众号AppID
WECHAT_APP_SECRET=公众号AppSecret
```
保存后执行 `sudo systemctl restart juzi-h5.service`。无需在聊天中发送 AppSecret,也不要将该私有文件加入 Git。然后重新检查 `/state/api/auth/config`,并在微信内访问站点完成真实授权测试。
同时须确认该公众号具备网页授权权限,公众号后台的「网页授权域名」是 `1me.xajuzi.com`。目前仅确认校验文件可访问,尚无法确认公众号后台实际设置。回调 URL 已准备为 `https://1me.xajuzi.com/state/api/auth/wechat/callback`。
初次部署阶段没有触发收费 Face++ 检测,没有更改既有报告或真实用户账号。后续闭环测试使用独立测试身份调用一次真实 Face++,详见闭环测试记录。真实微信账号联调仍待完成,不能将接口部署成功视为微信授权成功。
-69
View File
@@ -1,69 +0,0 @@
# 线上闭环测试(不含真实微信授权)
测试时间:2026-10-11;站点:`https://1me.xajuzi.com/state/`。
## 结论
真实线上测肤、完整报告存储与回看已跑通。测试使用项目自带的 C3 三视角示例照片和新建的独立浏览器身份,没有修改或删除既有用户报告。除明确标注的故障注入/演示测试外,真实闭环经过公网 HTTPS、nginx、生产 Node 服务和真实 Face++ 接口。
## 发现并修复
前端原先 45 秒取消测肤请求;后端两次 60 秒请求加 4 秒重试间隔,最长约 124 秒,导致网络慢或重试时前端提前失败。前端调整为 150 秒,与已部署的 nginx 150 秒超时配合,并新增请求成功、超时、过期响应丢弃及计时器清理回归测试。
线上已同步 `h5/js/app.js`,原文件备份为 `/home/ubuntu/juzi-app-before-closedloop-20261011.js`。静态 JS 响应 `Cache-Control: no-cache`。该超时修复已包含在提交 `3dda4ec` 中;本次将新增测试和记录同步纳入 Git,统一本地和线上版本。
## 话术及仓库同步
以线上提交 `3dda4ec` 中的最新 `reference/AI测肤报告页话术修改.md` 为准,其 SHA-256 与用户附件完全一致(`c871de9ac3ddd40410653da904cb0b800e24bdf550df53d60602645bab2aafbb`)。本地拉取时先备份并恢复了原有测试、文档及知识图谱改动,未丢弃未提交工作。
运行 `python3 tools/build_report_copy.py` 重新生成 `h5/js/report-copy.js`,将水分「改善」结论中的「水分分 {water_score}」同步到页面实际使用的话术。评分和推荐算法不变。部署后重启服务,让服务端新报告使用更新文案;已保存的历史报告继续读取原有快照。
## 已通过的检查
| 场景 | 验证方式与结果 |
|---|---|
| 核心评分 | 服务器运行 83 项引擎自测、86 项回归断言,全部通过 |
| 账号和报告 | 服务器隔离测试验证授权同意、CSRF、账号隔离、完整快照、最近 5 份、重启持久化、身份恢复及 OAuth 状态绑定/防重放 |
| 公网页面 | Chromium 经真实 HTTPS 访问登录、首页、隐私协议、档案、报告列表和报告;320/390/480 宽度无横向溢出 |
| 三连拍与语音 | 模拟摄像头完整正脸→右脸→左脸流程;14 条音频可获取、引导顺序正确、三次完成播报、无语音截断 |
| 档案保护 | 未同意隐私协议不能继续;未填写档案不能启动拍摄 |
| 相机降级 | 注入相机拒绝及模型不可用,系统相机文件输入仍可完成三视角流程;坏图提示错误后可重新选择 |
| 真实测肤 | 三视角样例经页面压缩上传,真实 Face++ 返回成功,记录已完成,服务记录耗时 1281 ms,综合分 74 |
| 完整报告 | 七张检测图加载、七个标签切换、图片放大及浏览器返回通过;后端保存三张照片、完整可视化数据与文案 |
| 历史恢复 | 清除会话 Cookie 后由浏览器本地身份恢复;从服务端再次打开报告,七张图片与文案和首次展示逐项一致 |
| 历史异常 | 浏览器侧注入列表 503 错误,错误提示与刷新重试恢复正常 |
| 检测异常 | 浏览器侧分别注入业务失败、断网和超时,均关闭分析弹层、保留档案并允许重拍;不产生虚假报告 |
| 人脸模型 | 公网真实模型加载正常,示例图能实际识别人脸并输出 68 个关键点 |
| 权限隔离 | 匿名读报告 401,另一个已登录身份读测试报告 404;跨站检测请求 403;缺图请求 400 |
| 文件/后台保护 | 后台接口、后台页面需认证;数据、源码、编码斜杠访问被拒绝 |
| 服务状态 | nginx 配置检查通过;nginx 和 juzi-h5 均 active;Node 仅监听 127.0.0.1:8080 |
真实调用记录:`R20261011-193351-PD7P`。本次只有一笔真实 Face++ 检测请求;故障测试不调用收费接口。测试报告保留在独立测试身份下,未清理或改写其他数据。
## 可复现命令
```bash
node h5/test/accounts.js
node h5/js/skin-score.js
node h5/test/regression.js
node h5/test/analyze-timeout.js
node h5/test/report-persistence.mjs
node h5/test/wechat-browser.mjs
BASE_URL=https://1me.xajuzi.com/state node h5/test/e2e-browser.mjs
H5_BASE_URL=https://1me.xajuzi.com/state/ H5_ARTIFACT_DIR=/tmp/juzi-production-ui-20261011 node h5/test/ui-20261009.mjs
H5_BASE_URL=https://1me.xajuzi.com/state/ node h5/test/browser-failures.mjs
# 显式开启:会新增独立测试身份和报告,并实际消耗一次 Face++ 调用。
RUN_LIVE_ANALYZE=1 H5_BASE_URL=https://1me.xajuzi.com/state/ node h5/test/production-loop.mjs
```
浏览器测试依赖全局 Playwright 和 Chromium。`wechat-browser.mjs` 使用隔离 HTTPS 及模拟微信响应,只验证我们的跳转、会话和身份流程,不代表真实微信授权通过。
本机截图/结果:`/tmp/juzi-production-loop-LqVf32/`、`/tmp/juzi-production-ui-20261011/`、`/tmp/juzi-e2e-report.png`。不记录身份凭证或密钥,不将报告快照/照片加入 Git。
## 验证边界
- 真实微信授权尚未完成:后续用户提供 AppID/AppSecret 后已配置并启用;基础接口凭据校验受到 IP 白名单限制,网页授权换码负向测试正常,真实微信授权仍需客户端完成。详见微信部署记录。
- 自动化不等同于真实手机相机验收。微信内置浏览器的权限、前后镜头、实际光线/姿态下自动抓拍和系统相机交互,需要最终真机验证。
- 这次是功能闭环和异常恢复检查,不是高并发压力测试或完整安全审计。
@@ -1,40 +0,0 @@
# 评分圈内居中、基础信息页固定与正脸语音修复
> 2026-10-13:报告顶部排版已按后续确认调整,以下 25px 年龄间距及原评分排列仅为历史记录。当前以《报告顶部评分与年龄排版-2026-10-13.md》为准;基础信息与语音修复不变。
## 范围
1. 报告:综合评分标题和分数在圆环内上下排列,作为一个整体垂直居中,标题与数字分别水平居中。数字右侧保留「分」。年龄标题到年龄数字的边界距离固定为 25 CSS px,不随屏宽比例增大;原显示文案不更名。
2. 基础信息:页面禁止纵向滚动、滚动链及下拉回弹,肤质轮播也不再把纵向手势交给页面。正常高度保留原间距;短视口只压缩纵向留白及肤质插画的可用高度,控件、说明、提交按钮完整可见,不以截掉下半页实现禁滚。出生年月、性别、省市的独立滚轮弹层仍支持纵向滑动。触摸防回弹监听只挂在基础信息页,不拦截弹层或报告页。
3. 语音:根因在 `HeadPose.check` 的正脸分支——正脸角度偏向一侧时,用「请向左/右转头」提示回正,和第二步侧脸指令混淆。现在正脸角度不合格统一提示「请正对屏幕」,不播侧脸转头指令;`setHint` 还按当前步骤和正脸照片是否已保存做防护。下一步语音必须有上一张已校验保存的照片,既有单通道队列保证「拍摄完成」先播完、再播侧脸引导。侧脸阶段的方向提示不变。
不更改拍照角度/距离/光线/稳定时长阈值,不改检测算法、报告保存、推荐、微信配置或数据。现有白色人头扫描页和三组报告跟手交互不变。未追踪的 `new_feedback/` 不纳入提交。
## 验证
本地 8080 服务运行后:
```bash
H5_ARTIFACT_DIR=/tmp/juzi-profile-voice-fix-20261012 node h5/test/report-touch-layout.mjs
H5_PROFILE_FONTS=1 H5_ARTIFACT_DIR=/tmp/juzi-profile-voice-fix-20261012 node h5/test/profile-interaction.mjs
node h5/test/capture-quality-browser.mjs
node h5/test/customer-feedback-second.js
node h5/test/customer-feedback-fourth.js
node h5/test/customer-feedback-fourth.mjs
node h5/test/customer-feedback-third.mjs
node h5/test/scan-placeholder.mjs
node h5/test/login-performance.mjs
node h5/test/report-persistence.mjs
node h5/test/recommendation.js
node h5/test/regression.js
```
- 五种屏宽下检查 0/75/82/100/缺失分数,标题加分数整体居中、均在圆内,年龄间距精确为 25px,报告的纵向滚动与三组横滑保留。
- 基础信息在 320×568、375×667、375×726、390×664、414×896、480×726、375×440 下不滚动且控件完整;真实触摸纵拖及鼠标滚轮不移动页面,之后横滑仍正常。用真实纵向触摸确认出生年月滚轮可改变选择,验证取消不保存以及账号隔离/重载记忆。
- 用真实本地人脸模型和已有照片组成合成相机视频:先提供侧脸作为不合格正脸,停留第一步并实际播「请正对屏幕」,无「转头」/下一步/完成音;再提供合格正脸,最终 JPEG 校验通过后自动保存并播「拍摄完成」,实际音频播完再开始第二步引导,随后完成三视图检测流程。
- 语音测试记录真实 MP3 解码后的 WebAudio 起播时间及当时屏幕步骤,不把语音文件预加载误认为起播。浏览器、无音频支持、真机系统音量/权限等行为仍以设备实际能力为准。
- 浏览器测试拦截模拟账号和分析响应或使用隔离数据服务,不写线上报告、不调用付费接口。
## 发布
基线 `2a49ebd`,目标 `ubuntu@1me.xajuzi.com:/home/ubuntu/juzi`、`juzi-h5.service`。沿用 Git bundle 快进同步,不代用户推送 origin,不改服务器配置和历史报告。发布后经公网执行布局、基础信息和真实自动拍照/语音测试,核对资源哈希、服务健康及匿名访问保护。
Binary file not shown.
@@ -1,2 +0,0 @@
1 拍摄的时候,拍摄完前一张图片的时候,需要有一停顿提示用户 拍摄下一张。 这样用户有心理预期。
2 报告页面的 "紧塑力 活力感 稳定力" 这个部分还是改回原来的布局,保留点击照片放大的功能就行。
Binary file not shown.
@@ -1,37 +0,0 @@
# 傅艳NEW与项思炼的会话 2026年10月12日
> 查看原消息记录,可点击[回到会话](https://applink.feishu.cn/client/message/link/open?token=Amqujz9KgEyzasxJCtuBi%2BE%3D)
傅艳NEW 2026年10月12日 10:16
@傅艳NEW 傅老师有几个问题需要和您反馈下:
这里我们的诉求是做成滑动和点击都可以选中的方式,技术上能做到吗?
![exported\_img\_v3\_0216d\_92abffb2\-da3a\-42d4\-bd42\-6d1b6a864e3g\.png](图片和附件/exported_img_v3_0216d_92abffb2-da3a-42d4-bd42-6d1b6a864e3g.png)
这里目前这样可以点开大图需要保留,在此基础上我们希望消费者脸占比大一点,就是只展示头部,背景少一点;
![exported\_img\_v3\_0216d\_d5d64a81\-acad\-4db9\-970c\-2dd1398b532g\.png](图片和附件/exported_img_v3_0216d_d5d64a81-acad-4db9-970c-2dd1398b532g.png)
报告中皱纹的文案可以拆的更细一点吗?把抬头纹、法令纹\(左右\)、鱼尾纹(左右)、眼部细纹\(左右\)、嘴角纹\(左右\)、眉间纹、额头纹、脸颊纹\(左右\)的具体指标全部说明;
这里平滑度这里有一些框,但写的结果是无明显粗大毛孔与黑头;那这里框的是什么?
![exported\_img\_v3\_0216d\_ee1903ba\-96ef\-4778\-9891\-027588093c7g\.jpeg](图片和附件/exported_img_v3_0216d_ee1903ba-96ef-4778-9891-027588093c7g.jpeg)
所有类似的黄色按钮的色号与我们设计要求不一致;
![exported\_img\_v3\_0216d\_718c2f13\-c978\-4e07\-bf72\-21b24236bd6g\.png](图片和附件/exported_img_v3_0216d_718c2f13-c978-4e07-bf72-21b24236bd6g.png)
这里依然存在断句问题,我们希望无论什么手机,宽幅多少,这里都用技术方法强制显示这种断句方式;
![exported\_img\_v3\_0216d\_eec8b07b\-be07\-4d37\-9a9f\-4057c5afc56g\.png](图片和附件/exported_img_v3_0216d_eec8b07b-be07-4d37-9a9f-4057c5afc56g.png)
我们目前点开链接会出现严重卡顿,是因为测试版本还是成品就是这样?
这里的文案和我们设计稿内给出的不一致,需要修改
![exported\_img\_v3\_0216d\_40a9e343\-5d09\-4760\-aa80\-6d13cc9ac8eg\.png](图片和附件/exported_img_v3_0216d_40a9e343-5d09-4760-aa80-6d13cc9ac8eg.png)
我们设置的字体大小希望用技术方式在不同型号的手机上呈现相同大小的字体,不要随着手机型号或者大小有改变
@@ -1,40 +0,0 @@
# 傅艳NEW与项思炼的会话 2026年10月12日
> 查看原消息记录,可点击[回到会话](https://applink.feishu.cn/client/message/link/open?token=Amqujz9KgEyzasytjPTAC8k%3D)
傅艳NEW 2026年10月12日 17:47
@傅艳NEW 傅老师我们有几个问题需要反馈:
这里需要修改为游客登陆
![exported\_img\_v3\_0216d\_aaa6c4cf\-bb45\-444e\-a75b\-1a142079f90g\.png](图片和附件/exported_img_v3_0216d_aaa6c4cf-bb45-444e-a75b-1a142079f90g.png)
拍摄不成功请直接在拍摄处重来,不要在报告页体现
![exported\_img\_v3\_0216d\_b4a8c873\-2c99\-47c7\-9910\-ebd1144100cg\.png](图片和附件/exported_img_v3_0216d_b4a8c873-2c99-47c7-9910-ebd1144100cg.png)
报告处的皱纹文案需要调整,整理好后给到技术
![exported\_img\_v3\_0216d\_f853f4b9\-3b5d\-453e\-91ce\-8696787b374g\.png](图片和附件/exported_img_v3_0216d_f853f4b9-3b5d-453e-91ce-8696787b374g.png)
这里需要做成动态扫描的感觉,而不是一张不动的图
![exported\_img\_v3\_0216d\_dd91f5b9\-0e52\-4631\-aa66\-3ff9ef74c4bg\.jpeg](图片和附件/exported_img_v3_0216d_dd91f5b9-0e52-4631-aa66-3ff9ef74c4bg.jpeg)
这里前面说了要加的内容并没有呈现
![exported\_img\_v3\_0216d\_48aff2c4\-70c9\-46fb\-a54f\-6d64a11f2bag\.png](图片和附件/exported_img_v3_0216d_48aff2c4-70c9-46fb-a54f-6d64a11f2bag.png)
这里需要的呈现形式如图:
![exported\_img\_v3\_0216d\_149f31b5\-7891\-42d9\-8b90\-d4a62ed533dg\.jpeg](图片和附件/exported_img_v3_0216d_149f31b5-7891-42d9-8b90-d4a62ed533dg.jpeg)
**蓝框中的文字组成为:**
**近期优先关注:xxx(分数最低的那个:紧塑力/透亮感/稳韧力)\+下面内容三选一:**
**强化紧塑力,提拉轮廓抚平细纹。**
**提升透亮感,补水提亮加强防晒。**
**增强稳韧力,舒缓泛红强韧屏障。**
蓝框内句句子呈现形式例子如下:
**近期优先关注:紧塑力**
**强化紧塑力,提拉轮廓抚平细纹。**
Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

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