Ver Fonte

DOC-2026-11-08-signature-landscape-fix: 横屏适配修复 (S1/S2/S3)

E2E Test Bot há 4 dias atrás
pai
commit
adb032a61

+ 16 - 11
cfc-frontend/components/hand-signature/hand-signature.vue

@@ -142,6 +142,11 @@ export default {
         }).exec()
       } catch (e) {}
     },
+    // 横屏旋转等布局变化后由调用方触发:重新查询 canvas 实际位置与尺寸,
+    // 保证 getPos() 坐标换算/导出尺寸使用最新 rect(loadRect 幂等,可重复调用)
+    refreshRect: function() {
+      this.loadRect()
+    },
     getPos: function(e) {
       var touch = e.touches && e.touches[0]
       var cx = touch ? touch.clientX : (e.clientX || 0)
@@ -283,12 +288,12 @@ export default {
 .signature-agree {
   display: flex;
   align-items: flex-start;
-  margin-bottom: 16rpx;
+  margin-bottom: 8px;
 }
 .agree-box {
-  flex: 0 0 32rpx;
-  width: 32rpx;
-  height: 32rpx;
+  flex: 0 0 16px;
+  width: 16px;
+  height: 16px;
   margin-right: 12rpx;
   margin-top: 2rpx;
   border: 2rpx solid #c8c9cc;
@@ -303,13 +308,13 @@ export default {
   border-color: $accent-indigo;
 }
 .agree-tick {
-  font-size: calc(22rpx * var(--font-scale, 1));
+  font-size: calc(11px * var(--font-scale, 1));
   color: $app-surface;
   line-height: 1;
 }
 .agree-text {
   flex: 1;
-  font-size: calc(24rpx * var(--font-scale, 1));
+  font-size: calc(12px * var(--font-scale, 1));
   color: $facade-text-body;
   line-height: 1.5;
 }
@@ -339,11 +344,11 @@ export default {
   margin-top: 16rpx;
 }
 .btn-sign-clear {
-  flex: 0 0 160rpx;
+  flex: 0 0 80px;
   height: 72rpx;
   line-height: 72rpx;
-  margin-right: 20rpx;
-  font-size: calc(26rpx * var(--font-scale, 1));
+  margin-right: 10px;
+  font-size: calc(13px * var(--font-scale, 1));
   color: $facade-text-body;
   background: $facade-fill-2;
   border: none;
@@ -353,10 +358,10 @@ export default {
   opacity: 0.5;
 }
 .btn-sign-confirm {
-  flex: 0 0 200rpx;
+  flex: 0 0 100px;
   height: 72rpx;
   line-height: 72rpx;
-  font-size: calc(26rpx * var(--font-scale, 1));
+  font-size: calc(13px * var(--font-scale, 1));
   color: $app-surface;
   background: linear-gradient(135deg, $accent-indigo 0%, $accent-indigo-deep 100%);
   border: none;

+ 64 - 5
cfc-frontend/pages/signature/signature.vue

@@ -76,9 +76,12 @@ export default {
       if (text) this.agreeText = text
     }
     this.canvasHeight = this.computeCanvasHeight()
+    this.registerResizeListener()
     this.enterLandscape()
   },
   onUnload: function() {
+    // 注销窗口尺寸变化监听,防泄漏
+    this.unregisterResizeListener()
     // 离开签名页恢复竖屏,不污染其它页面
     this.restorePortrait()
   },
@@ -114,8 +117,17 @@ export default {
       // #ifdef MP-WEIXIN
       try {
         if (typeof wx !== 'undefined' && typeof wx.setPageOrientation === 'function') {
+          var self = this
           wx.setPageOrientation({
-            orientation: 'landscape'
+            orientation: 'landscape',
+            success: function() {
+              // 切横屏即时生效时 onWindowResize 未必触发:兜底重算高度 + 刷新组件 rect
+              self.refreshLandscapeLayout()
+            },
+            complete: function() {
+              // 部分机型只走 complete:再兜底一次(幂等,重复调无害)
+              self.refreshLandscapeLayout()
+            }
           })
         }
       } catch (e) {}
@@ -200,6 +212,53 @@ export default {
       if (this._backed) return
       this._backed = true
       uni.navigateBack()
+    },
+    // 监听窗口尺寸变化(旋转后重算画布高度 + 刷新组件 rect),平台分流条件编译
+    registerResizeListener: function() {
+      var self = this
+      this._onWindowResize = function() {
+        self.refreshLandscapeLayout()
+      }
+      // #ifdef MP-WEIXIN
+      try {
+        if (typeof wx !== 'undefined' && typeof wx.onWindowResize === 'function') {
+          wx.onWindowResize(this._onWindowResize)
+        }
+      } catch (e) {}
+      // #endif
+      // #ifdef H5
+      try {
+        if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
+          window.addEventListener('resize', this._onWindowResize)
+        }
+      } catch (e) {}
+      // #endif
+    },
+    // 注销窗口尺寸变化监听,防泄漏
+    unregisterResizeListener: function() {
+      // #ifdef MP-WEIXIN
+      try {
+        if (typeof wx !== 'undefined' && typeof wx.offWindowResize === 'function' && this._onWindowResize) {
+          wx.offWindowResize(this._onWindowResize)
+        }
+      } catch (e) {}
+      // #endif
+      // #ifdef H5
+      try {
+        if (typeof window !== 'undefined' && typeof window.removeEventListener === 'function' && this._onWindowResize) {
+          window.removeEventListener('resize', this._onWindowResize)
+        }
+      } catch (e) {}
+      // #endif
+      this._onWindowResize = null
+    },
+    // 横屏/竖屏切换后的统一重算入口:更新 canvasHeight prop(响应式生效)并刷新组件 rect
+    refreshLandscapeLayout: function() {
+      this.canvasHeight = this.computeCanvasHeight()
+      var pad = this.$refs.signaturePad
+      if (pad && typeof pad.refreshRect === 'function') {
+        pad.refreshRect()
+      }
     }
   }
 }
@@ -229,7 +288,7 @@ export default {
   text-align: center;
 }
 .rotate-hint-text {
-  font-size: calc(26rpx * var(--font-scale, 1));
+  font-size: calc(13px * var(--font-scale, 1));
   color: $brand-primary;
 }
 
@@ -240,14 +299,14 @@ export default {
 }
 .sig-title {
   display: block;
-  font-size: calc(32rpx * var(--font-scale, 1));
+  font-size: calc(16px * var(--font-scale, 1));
   font-weight: bold;
   color: $facade-text-strong;
 }
 .sig-subtitle {
   display: block;
   margin-top: 4px;
-  font-size: calc(24rpx * var(--font-scale, 1));
+  font-size: calc(12px * var(--font-scale, 1));
   color: $facade-text-muted;
 }
 
@@ -277,7 +336,7 @@ export default {
   padding: 0;
   border: none;
   border-radius: 24rpx;
-  font-size: calc(30rpx * var(--font-scale, 1));
+  font-size: calc(15px * var(--font-scale, 1));
   text-align: center;
 }
 .sig-btn::after {