feat(h5): align October UI and add WeChat auth with saved reports
This commit is contained in:
@@ -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`。
|
||||
@@ -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++ 个人信息与隐私保护政策」(包含儿童相关章节)。本次未发现独立的品牌方用户协议文件,未凭空编写法律条款;正式发布前请业务/法务确认现有政策是否覆盖品牌方的账号关联、报告存储、保存期限和删除渠道。
|
||||
Reference in New Issue
Block a user