Browse Source

fix: 修改悬浮按钮样式

liangan 3 weeks ago
parent
commit
8e70a0c206
2 changed files with 50 additions and 117 deletions
  1. 49 116
      src/components/CustomerServiceFab.vue
  2. 1 1
      src/layouts/tabbar.vue

+ 49 - 116
src/components/CustomerServiceFab.vue

@@ -1,6 +1,6 @@
 <script lang="ts" setup>
-import { onShow } from '@dcloudio/uni-app'
 import { getConfigByCode } from '@/api/common'
+import { toPage } from '@/utils/page'
 import { openH5WhatsApp } from '@/utils/social'
 import { toast } from '@/utils/toast'
 
@@ -8,10 +8,13 @@ const props = defineProps<{
   bottomOffset?: number
 }>()
 
-const STORAGE_KEY = 'customer_service_fab_position_v1'
+const active = ref<boolean>(false)
 
-const x = ref<number>(0)
-const y = ref<number>(0)
+const TABBAR_PAGES = [
+  'pages/index/index',
+  'pages/income/income',
+  'pages/mine/mine',
+]
 
 function rpxToPx(rpx: number) {
   const sys = uni.getSystemInfoSync()
@@ -19,89 +22,33 @@ function rpxToPx(rpx: number) {
   return (rpx * windowWidth) / 750
 }
 
-function getBottomLimitPx() {
-  const sys = uni.getSystemInfoSync() as any
-  const bottomOffsetPx = rpxToPx(props.bottomOffset ?? 0)
-  const safeBottomPx = Number(sys?.safeAreaInsets?.bottom) || 0
-  return bottomOffsetPx + safeBottomPx
-}
-
-function initDefaultPosition() {
-  const sys = uni.getSystemInfoSync()
-  const windowWidth = sys.windowWidth || 375
-  const windowHeight = sys.windowHeight || 667
-  const sizePx = rpxToPx(80)
-  const rightInsetPx = rpxToPx(24)
-  const bottomInsetPx = rpxToPx(-86)
-  const bottomOffsetPx = getBottomLimitPx()
-  x.value = Math.max(0, windowWidth - sizePx - rightInsetPx)
-  y.value = Math.max(0, windowHeight - sizePx - bottomOffsetPx - bottomInsetPx)
-}
-
-function clampPosition() {
-  const sys = uni.getSystemInfoSync()
-  const windowWidth = sys.windowWidth || 375
-  const windowHeight = sys.windowHeight || 667
-  const sizePx = rpxToPx(80)
-  const bottomOffsetPx = getBottomLimitPx()
-  const maxX = Math.max(0, windowWidth - sizePx)
-  const maxY = Math.max(0, windowHeight - sizePx - bottomOffsetPx)
-  x.value = Math.min(Math.max(0, x.value), maxX)
-  y.value = Math.min(Math.max(0, y.value), maxY)
-}
-
-function restorePosition() {
-  try {
-    const raw = uni.getStorageSync(STORAGE_KEY)
-    if (!raw) {
-      initDefaultPosition()
-      return
-    }
-    const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw
-    const nx = Number(parsed?.x)
-    const ny = Number(parsed?.y)
-    if (Number.isFinite(nx) && Number.isFinite(ny)) {
-      x.value = nx
-      y.value = ny
-      clampPosition()
-      return
-    }
-    initDefaultPosition()
-  }
-  catch {
-    initDefaultPosition()
-  }
+function getCurrentRoutePath() {
+  const pages = getCurrentPages() as any[]
+  const last = pages?.[pages.length - 1]
+  const route = String(last?.route || '')
+  return route.replace(/^\//, '')
 }
 
-function persistPosition() {
-  try {
-    uni.setStorageSync(STORAGE_KEY, JSON.stringify({ x: x.value, y: y.value }))
-  }
-  catch {
-  }
+function isTabbarPage() {
+  const route = getCurrentRoutePath()
+  return TABBAR_PAGES.includes(route)
 }
 
-function persistPositionClamped() {
-  clampPosition()
-  persistPosition()
+function getBottomOffsetPx() {
+  const sys = uni.getSystemInfoSync() as any
+  const extraOffsetPx = rpxToPx(props.bottomOffset ?? 0)
+  const safeBottomPx = Number(sys?.safeAreaInsets?.bottom) || 0
+  const tabbarHeightPx = isTabbarPage() ? 50 : 0
+  return extraOffsetPx + safeBottomPx + tabbarHeightPx
 }
 
-onShow(() => {
-  restorePosition()
+const fabCustomStyle = computed(() => {
+  const bottomPx = getBottomOffsetPx()
+  return `bottom: ${bottomPx}px;`
 })
 
-function handleMoveChange(e: any) {
-  const detail = e?.detail
-  const nx = Number(detail?.x)
-  const ny = Number(detail?.y)
-  if (Number.isFinite(nx))
-    x.value = nx
-  if (Number.isFinite(ny))
-    y.value = ny
-  clampPosition()
-}
-
 async function openCustomerService() {
+  active.value = false
   try {
     const res = await getConfigByCode({ code: 'live_chat' })
     const value = res?.data?.valueInfo
@@ -115,54 +62,40 @@ async function openCustomerService() {
     toast.info('客服暂不可用')
   }
 }
+
+function openHelpCenter() {
+  active.value = false
+  toPage({ url: '/pages/mine/helpCenter' })
+}
 </script>
 
 <template>
-  <movable-area class="customer-fab-area">
-    <movable-view
-      :x="x"
-      :y="y"
-      direction="all"
-      :inertia="false"
-      :animation="false"
-      :out-of-bounds="false"
-      class="customer-fab-movable"
-      @change="handleMoveChange"
-      @touchend="persistPositionClamped"
-      @touchcancel="persistPositionClamped"
-    >
-      <image
-        src="/static/icons/whatsapp.png"
-        class="customer-fab-trigger__icon"
-        mode="heightFix"
-        @click="openCustomerService"
-      />
-    </movable-view>
-  </movable-area>
+  <wd-fab v-model:active="active" position="right-bottom" direction="top" :custom-style="fabCustomStyle" :expandable="false" :draggable="true">
+    <template #trigger>
+      <view class="w-80rpx">
+        <view class="customer-fab-action mb-12rpx" @click="openCustomerService">
+          <image src="/static/icons/whatsapp.png" class="customer-fab-action__icon" mode="heightFix" />
+        </view>
+        <view class="customer-fab-action" @click="openHelpCenter">
+          <image src="/static/icons/icon-info.png" class="customer-fab-action__icon" mode="heightFix" />
+        </view>
+      </view>
+    </template>
+  </wd-fab>
 </template>
 
 <style lang="scss" scoped>
-.customer-fab-area {
-  position: fixed;
-  left: 0;
-  top: 0;
-  width: 100vw;
-  height: 100vh;
-  pointer-events: none;
-  z-index: 999;
-}
-
-.customer-fab-movable {
-  pointer-events: auto;
-  transition: none;
+.customer-fab-action {
+  box-sizing: border-box;
   width: 80rpx;
   height: 80rpx;
+  border-radius: 50%;
+  padding: 0;
+  background-color: #fff;
 }
 
-.customer-fab-trigger__icon {
-  box-shadow: 0 12rpx 30rpx rgba(0, 0, 0, 0.16);
-  height: 80rpx;
+.customer-fab-action__icon {
   width: 80rpx;
-  border-radius: 50%;
+  height: 80rpx;
 }
 </style>

+ 1 - 1
src/layouts/tabbar.vue

@@ -15,7 +15,7 @@ const themeVars: ConfigProviderThemeVars = {
   <wd-config-provider :theme-vars="themeVars">
     <slot />
     <!-- #ifdef H5 -->
-    <CustomerServiceFab :bottom-offset="180" />
+    <CustomerServiceFab :bottom-offset="120" />
     <!-- #endif -->
     <FgTabbar />
     <wd-toast />