Browse Source

修复撤回的bug

liudan 2 months ago
parent
commit
ce969176b0
1 changed files with 106 additions and 18 deletions
  1. 106 18
      src/pages/myConsultRoom/page/treatment/treatment.vue

+ 106 - 18
src/pages/myConsultRoom/page/treatment/treatment.vue

@@ -323,9 +323,9 @@
             </view>
         </view>
         <view v-if="showlongBtn" class="longView" @tap="closeLongBtn">
-            <view class="longbtn" :style="'top:' + longBtnTop + 'px; left:' + longBtnLeft + 'px'">
-                <view @tap="copyTextFun" v-if="showCopyBtn">复制</view>
-                <view @tap="cancelSend">撤回</view>
+            <view class="longbtn" :style="'top:' + longBtnTop + 'px; left:' + longBtnLeft + 'px'" @tap.stop>
+                <view class="longbtn-item" @tap="copyTextFun" v-if="showCopyBtn">复制</view>
+                <view class="longbtn-item" @tap="cancelSend">撤回</view>
             </view>
         </view>
         <!-- 视频播放弹窗(H5) -->
@@ -2043,16 +2043,79 @@ export default {
             } else {
                 showCopyBtn = true;
             }
+
+            // 计算弹层位置:以触摸点为锚,优先显示在上方,并做边界裁剪,避免溢出屏幕
+            let pos = this._calcLongBtnPos(event, showCopyBtn);
+
             this.setData({
                 showlongBtn: true,
-                longBtnLeft: event.detail.x,
-                longBtnTop: event.detail.y,
+                longBtnLeft: pos.left,
+                longBtnTop: pos.top,
                 copyText: item.consultText,
                 clickMsgID: item.msgID,
                 showCopyBtn: showCopyBtn
             });
         },
 
+        /**
+         * 计算长按弹层位置
+         * @param {Object} event 长按事件
+         * @param {Boolean} showCopyBtn 是否显示复制按钮(决定弹层高度)
+         */
+        _calcLongBtnPos: function (event, showCopyBtn) {
+            const sys = uni.getSystemInfoSync();
+            const vw = sys.windowWidth;
+            const vh = sys.windowHeight;
+            const ratio = vw / 750; // rpx -> px
+            const popupW = 140 * ratio; // .longbtn 宽度 140rpx
+            const items = showCopyBtn ? 2 : 1;
+            const popupH = items * 80 * ratio + 2; // 每项 80rpx + 分割线
+            const margin = 12; // 距屏幕边缘安全间距(px)
+
+            // 触摸点坐标(多源兼容:H5 原生触摸 / uni longpress detail)
+            let px = 0;
+            let py = 0;
+            const detail = event.detail || {};
+            const changed = event.changedTouches && event.changedTouches[0];
+            const touches = event.touches && event.touches[0];
+            if (changed) {
+                px = changed.clientX;
+                py = changed.clientY;
+            } else if (touches) {
+                px = touches.clientX;
+                py = touches.clientY;
+            } else if (detail.x !== undefined && detail.x !== null) {
+                px = detail.x;
+                py = detail.y;
+            }
+
+            // 水平:以触摸点为中心,裁剪到屏幕内
+            let left = px - popupW / 2;
+            if (left < margin) {
+                left = margin;
+            }
+            if (left + popupW > vw - margin) {
+                left = vw - popupW - margin;
+            }
+            if (left < margin) {
+                left = margin;
+            }
+
+            // 垂直:优先在触摸点上方,空间不足则下方,再裁剪到屏幕内
+            let top = py - popupH - 10;
+            if (top < margin) {
+                top = py + 10; // 上方空间不足,改到下方
+            }
+            if (top + popupH > vh - margin) {
+                top = vh - popupH - margin;
+            }
+            if (top < margin) {
+                top = margin;
+            }
+
+            return { left: left, top: top };
+        },
+
         /**
          * 关闭长按弹框
          * @param {*} event
@@ -2072,7 +2135,8 @@ export default {
          * @param {*} event
          */
         copyTextFun: function (event) {
-            let { copyTextFun: copyText } = this;
+            let copyText = this.copyText;
+            this.closeLongBtn();
             uni.setClipboardData({
                 data: copyText,
                 complete: function () {},
@@ -2087,6 +2151,7 @@ export default {
             if (!this.ifOnLine()) {
                 return;
             }
+            this.closeLongBtn();
             let { clickMsgID } = this;
             const patientData = Cache.get('patientData');
             const userData = Cache.get('userData');
@@ -3713,26 +3778,49 @@ page {
 }
 
 .longbtn {
-    width: 120rpx;
-    position: relative;
+    width: 140rpx;
+    position: absolute;
     z-index: 9999;
-    background: #fff;
+    background: rgba(38, 38, 42, 0.94);
     text-align: center;
-    border-radius: 12rpx;
-    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.12);
+    border-radius: 16rpx;
+    box-shadow: 0 8rpx 28rpx rgba(0, 0, 0, 0.28);
     overflow: hidden;
+    transform-origin: center top;
+    animation: longbtn-in 0.16s ease-out both;
 }
 
-.longbtn > view {
-    height: 72rpx;
-    line-height: 72rpx;
+@keyframes longbtn-in {
+    from {
+        opacity: 0;
+        transform: scale(0.9) translateY(6rpx);
+    }
+    to {
+        opacity: 1;
+        transform: scale(1) translateY(0);
+    }
+}
+
+.longbtn-item {
+    height: 80rpx;
+    line-height: 80rpx;
     font-size: 28rpx;
-    color: #1f2329;
-    border-bottom: 1rpx solid #f0f2f5;
+    color: #ffffff;
+    position: relative;
+}
+
+.longbtn-item + .longbtn-item::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 16rpx;
+    right: 16rpx;
+    height: 1rpx;
+    background: rgba(255, 255, 255, 0.12);
 }
 
-.longbtn > view:last-child {
-    border-bottom: none;
+.longbtn-item:active {
+    background: rgba(255, 255, 255, 0.08);
 }
 
 /* ============== 其它兼容 ============== */