|
|
@@ -0,0 +1,85 @@
|
|
|
+# 手签名横屏适配修复 任务书
|
|
|
+
|
|
|
+- 需求编号:DOC-2026-11-08-signature-landscape-fix
|
|
|
+- 需求来源:主理人反馈(小程序端)
|
|
|
+- 状态:待开发
|
|
|
+- 关联需求变更:见 `docs/需求分析/2026-11-08-手签名横屏适配需求变更.md`(随派发同步合入)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、需求原话
|
|
|
+
|
|
|
+> 手签名功能,横屏下签名的区域太小了,文字和按钮都过大。而且签名也没显示出笔记来。
|
|
|
+
|
|
|
+## 二、现状核查(已确认根因)
|
|
|
+
|
|
|
+涉改文件(均基于 `origin/cfclub` 最新):
|
|
|
+
|
|
|
+1. `cfc-frontend/pages/signature/signature.vue`(311 行,签名页,横屏全屏,`navigationStyle:custom`)
|
|
|
+2. `cfc-frontend/components/hand-signature/hand-signature.vue`(367 行,通用手签名组件,**当前实际仅 signature.vue 引用**;checkout.vue 仅跳转、不渲染组件,改动零波及)
|
|
|
+
|
|
|
+### 根因 R1:签名区域太小 —— canvasHeight 只在竖屏时算过一次
|
|
|
+
|
|
|
+- `signature.vue onLoad()` 里同步调用 `computeCanvasHeight()`,此时仍处竖屏:`uni.getWindowInfo().windowHeight`(如 844px)− reserved(174/214) → `canvasHeight ≈ 670px`。
|
|
|
+- 随后 `enterLandscape()` 用 `wx.setPageOrientation({orientation:'landscape'})` **异步**切横屏;横屏后视口高 = 短边(如 390px),但 `canvasHeight` **从未重算**。
|
|
|
+- canvas 实际高 670px,而 `.sig-canvas-area{flex:1; overflow:hidden}` 可视高度仅约 216px → **画布被裁剪成顶部窄条,"签名区域太小"**。
|
|
|
+- 微信 `setPageOrientation` 无 success 回调链更新高度;页面也没有 `onResize` / `wx.onWindowResize` / H5 resize 监听 → 旋转后高度永远不更新。
|
|
|
+
|
|
|
+### 根因 R2:文字/按钮过大 —— rpx 基准在横屏下放大 ~2.2 倍
|
|
|
+
|
|
|
+- 微信 rpx 定义:750rpx = 当前**屏幕宽度**。竖屏宽 390 → 1rpx≈0.52px;横屏宽 844 → 1rpx≈1.13px,**所有 rpx 字号相对竖屏放大 ~2.17 倍**。
|
|
|
+- signature.vue:`.sig-title` 32rpx、`.sig-subtitle` 24rpx、`.sig-btn` 30rpx、`.rotate-hint-text` 26rpx —— 横屏全被放大,而 `.sig-btn` 高度 72px / `.sig-footer` 高 92px 是**固定 px 不变** → 文字过大、按钮比例失调。
|
|
|
+- 组件内同理:`.agree-text` 24rpx、`.agree-tick` 22rpx、`.btn-sign-*` 26rpx、`.signature-actions` 按钮 160/200rpx 定宽。
|
|
|
+- 结论:**横屏页字号/按钮尺寸应改用固定 px(或按视口短边换算),不得依赖 rpx**。
|
|
|
+
|
|
|
+### 根因 R3:签名没显示笔记 —— rect 未随旋转刷新,坐标整体错位
|
|
|
+
|
|
|
+- 组件 `loadRect()` 仅在 `mounted`(竖屏)执行一次(+300ms 重试一次);旋转后 canvas 的布局(left/top/width/height)全部变化,但 `this.rect` 仍是竖屏旧值。
|
|
|
+- `getPos()` 用 `clientX-rect.left / clientY-rect.top` 换算画布坐标 → 横屏下整体错位,笔迹画到 canvas 可视区外(被 `overflow:hidden` 裁掉)→ **"签名没显示笔记"**。
|
|
|
+- `handleConfirm` 导出也用旧 rect 尺寸。
|
|
|
+
|
|
|
+### 波及面确认(改动安全):
|
|
|
+
|
|
|
+- `hand-signature` 组件引用方:`grep` 全前端仅 `signature.vue` 实际使用 `<hand-signature>`;checkout.vue 只有 `hasHandSignatureField/purchase-signature-block` 字样,不 import、不渲染 → **组件改动安全,零波及其它页面**。
|
|
|
+- signature 页调用方:health-plan-summary.vue / checkout.vue / consignee-edit.vue(均为 navigateTo 跳转 + eventChannel 回传,不改它们)。
|
|
|
+- 无后端改动,纯前端 2 文件纵切修复。
|
|
|
+
|
|
|
+## 三、需求变更定义
|
|
|
+
|
|
|
+### 变更 S1:横屏尺寸重算 —— canvasHeight 随旋转刷新(signature.vue)
|
|
|
+
|
|
|
+- 页面增加窗口尺寸变化监听(微信 `wx.onWindowResize`、H5 `window.addEventListener('resize')`;`onUnload` 注销,防泄漏),回调内:
|
|
|
+ - 重新 `computeCanvasHeight()`(用 `uni.getWindowInfo()` 当前值,横屏时 windowHeight=短边,如 390)并同步给组件(`ref` 传入的 `height` prop 变化即可,组件只需响应式接收)。
|
|
|
+ - 调用组件公开方法 `refreshRect()`(见 S3)重新 `loadRect()`。
|
|
|
+- `enterLandscape()` 在 `wx.setPageOrientation` 的 success/complete 回调里补一次同样的「重算高度 + refreshRect」兜底(setPageOrientation 即时生效时 onWindowResize 未必触发)。
|
|
|
+- `computeCanvasHeight()` 保留:横屏短边 − reserved(标题 66 + 底部栏 92 + 同意 40 + 留白 16)取 `h>160?h:160`,逻辑不变,只是**在旋转后重跑**。
|
|
|
+
|
|
|
+### 变更 S2:横屏字号/按钮尺寸 px 化(signature.vue + 组件)
|
|
|
+
|
|
|
+- 将签名页与组件内**所有 rpx 字号改为固定 px**(等价竖屏观感,横屏不再放大):
|
|
|
+ - signature.vue:`.sig-title` 32rpx→16px、`.sig-subtitle` 24rpx→12px、`.sig-btn` 30rpx→15px、`.rotate-hint-text` 26rpx→13px(保留 `calc(... * var(--font-scale))` 结构,只是把 rpx 换 px)。
|
|
|
+ - hand-signature.vue:`.agree-text` 24rpx→12px、`.agree-tick` 22rpx→11px、`.btn-sign-clear/.btn-sign-confirm` 26rpx→13px、`.signature-actions` 按钮定宽 160/200rpx→80/100px(margin-right 20rpx→10px)、`.agree-box` 32rpx→16px、`.signature-agree` margin 16rpx→8px。
|
|
|
+- 按钮高度(72px/92px)已是 px 不动;`line-height` 同步为 72px 已具备。
|
|
|
+- 目的:横屏与竖屏观感一致,消除 R2。
|
|
|
+
|
|
|
+### 变更 S3:组件公开 refreshRect() 并修复导出兜底(hand-signature.vue)
|
|
|
+
|
|
|
+- 在组件 methods 新增公开方法 `refreshRect()`:重新执行 `loadRect()`(复用现有 `query.select('.signature-canvas').boundingClientRect`)。
|
|
|
+- `getPos()` 防御:`rect` 为 null 时沿用现行为(回退 raw clientX/Y),不做额外改动;**核心修复由「旋转后调用 refreshRect() 刷新 rect」达成**。
|
|
|
+- `handleConfirm` 导出 x/y/width/height 用刷新后的 `this.rect`(现有代码已是 `var rect = this.rect || {...}`,会自动用新 rect,无需改导出逻辑,仅确认)。
|
|
|
+
|
|
|
+### 不修改:
|
|
|
+
|
|
|
+- 不改成竖屏内嵌签名(需求是"横屏全屏签名",保持)。
|
|
|
+- 不改 `pages.json` 注册、不改 `signature-bus.js`、不改后端。
|
|
|
+- 不改组件 `handleClear` / `_emitSignature` / eventChannel 回传链路。
|
|
|
+
|
|
|
+## 四、TDD 入池建议
|
|
|
+
|
|
|
+- 能力键:`signature.landscape.layout`(前端 UI 纵切,无独立后端接口)
|
|
|
+- 验收:真机/工具横屏下——① 画布高度等于可视区(短边 − 固定栏),无裁剪;② 文字/按钮尺寸与竖屏观感一致;③ 横屏书写笔迹实时可见、导出 dataUrl 完整;④ 旋转后(切回竖屏再横屏)rect 与高度仍正确;⑤ 不回归竖屏下 signature 页与 health summary / checkout / consignee-edit 跳转回传链路。
|
|
|
+
|
|
|
+## 五、风险与关联记录
|
|
|
+
|
|
|
+- 风险:`wx.setPageOrientation` 在部分安卓机型即时旋转时 canvas 会闪烁/重建,若刷新 rect 后仍偶发笔迹偏移,可在 `refreshRect` 的 boundingClientRect 回调成功后置 `hasDrawn` 不变即可(不加重绘逻辑,保持简单)。
|
|
|
+- 关联:无其它任务书依赖;纯前端纵切,可独立合入。
|