CustomerServiceFab.vue 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <script lang="ts" setup>
  2. import { getConfigByCode } from '@/api/common'
  3. import { toPage } from '@/utils/page'
  4. import { openH5WhatsApp } from '@/utils/social'
  5. import { toast } from '@/utils/toast'
  6. const props = defineProps<{
  7. bottomOffset?: number
  8. }>()
  9. const active = ref<boolean>(false)
  10. const TABBAR_PAGES = [
  11. 'pages/index/index',
  12. 'pages/income/income',
  13. 'pages/mine/mine',
  14. ]
  15. function rpxToPx(rpx: number) {
  16. const sys = uni.getSystemInfoSync()
  17. const windowWidth = sys.windowWidth || 375
  18. return (rpx * windowWidth) / 750
  19. }
  20. function getCurrentRoutePath() {
  21. const pages = getCurrentPages() as any[]
  22. const last = pages?.[pages.length - 1]
  23. const route = String(last?.route || '')
  24. return route.replace(/^\//, '')
  25. }
  26. function isTabbarPage() {
  27. const route = getCurrentRoutePath()
  28. return TABBAR_PAGES.includes(route)
  29. }
  30. function getBottomOffsetPx() {
  31. const sys = uni.getSystemInfoSync() as any
  32. const extraOffsetPx = rpxToPx(props.bottomOffset ?? 0)
  33. const safeBottomPx = Number(sys?.safeAreaInsets?.bottom) || 0
  34. const tabbarHeightPx = isTabbarPage() ? 50 : 0
  35. return extraOffsetPx + safeBottomPx + tabbarHeightPx
  36. }
  37. const fabCustomStyle = computed(() => {
  38. const bottomPx = getBottomOffsetPx()
  39. return `bottom: ${bottomPx}px;`
  40. })
  41. async function openCustomerService() {
  42. active.value = false
  43. try {
  44. const res = await getConfigByCode({ code: 'live_chat' })
  45. const value = res?.data?.valueInfo
  46. if (!value) {
  47. toast.info('客服暂不可用')
  48. return
  49. }
  50. openH5WhatsApp('live_chat', value)
  51. }
  52. catch {
  53. toast.info('客服暂不可用')
  54. }
  55. }
  56. function openHelpCenter() {
  57. active.value = false
  58. toPage({ url: '/pages/mine/helpCenter' })
  59. }
  60. </script>
  61. <template>
  62. <wd-fab v-model:active="active" position="right-bottom" :z-index="999" direction="top" :custom-style="fabCustomStyle" :expandable="false" :draggable="true">
  63. <template #trigger>
  64. <view class="w-68rpx">
  65. <image src="/static/icons/whatsapp-fb.png" class="customer-fab-action__icon mb-12rpx" mode="heightFix" @click="openCustomerService" />
  66. <image src="/static/icons/help-fb.png" class="customer-fab-action__icon" mode="heightFix" @click="openHelpCenter" />
  67. </view>
  68. </template>
  69. </wd-fab>
  70. </template>
  71. <style lang="scss" scoped>
  72. .customer-fab-action__icon {
  73. width: 68rpx;
  74. height: 68rpx;
  75. box-sizing: border-box;
  76. border-radius: 50%;
  77. background-color: #fff;
  78. }
  79. </style>