share.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <route lang="json5">
  2. {
  3. layout: 'default',
  4. style: {
  5. navigationStyle: 'custom',
  6. navigationBarTitleText: '%mine.pages.share.title%'
  7. }
  8. }
  9. </route>
  10. <script setup lang="ts">
  11. import tkiQrcode from 'tki-qrcode'
  12. import { getUserInfoHook } from '@/hooks/usePageAuth'
  13. import { t } from '@/locale'
  14. import { useUserStore } from '@/store'
  15. import { goBack } from '@/utils/page'
  16. import { toast } from '@/utils/toast'
  17. // 获取屏幕边界到安全区域距离
  18. const systemInfo = uni.getSystemInfoSync()
  19. const safeAreaInsets = systemInfo.safeAreaInsets
  20. const userStore = useUserStore()
  21. const baseUrl = import.meta.env.VITE_H5_BASE_URL
  22. // 推荐码
  23. const userInfo = computed(() => getUserInfoHook())
  24. const qrcodeConfig = ref<any>({
  25. val: `${baseUrl}?referrer=${userInfo.value.invitedCode}`, // 推荐链接
  26. size: 500,
  27. background: '#ffffff',
  28. foreground: '#000000',
  29. pdground: '#000000',
  30. icon: '/static/icons/logo.png', // 中间logo
  31. iconsize: 60, // logo占比
  32. onval: true,
  33. loadMake: true,
  34. showLoading: false,
  35. })
  36. // 社交平台配置
  37. const socialPlatforms = ref([
  38. {
  39. name: 'facebook',
  40. label: 'Facebook',
  41. icon: '/static/icons/facebook.png', // 占位图片路径
  42. },
  43. {
  44. name: 'whatsapp',
  45. label: 'Whatsapp',
  46. icon: '/static/icons/whatsapp.png', // 占位图片路径
  47. },
  48. {
  49. name: 'instagram',
  50. label: 'Instagram',
  51. icon: '/static/icons/instagram.png', // 占位图片路径
  52. },
  53. {
  54. name: 'twitter',
  55. label: 'Twitter',
  56. icon: '/static/icons/twitter.png', // 占位图片路径
  57. },
  58. ])
  59. // 复制推荐码
  60. function copyReferrerCode() {
  61. uni.setClipboardData({
  62. data: userInfo.value.invitedCode,
  63. success: () => {},
  64. })
  65. }
  66. // 生成邀请注册分享链接
  67. function generateInviteShareLink() {
  68. // 邀请注册链接
  69. const inviteUrl = `${baseUrl}?referrer=${userInfo.value.invitedCode}`
  70. // 分享文案格式:[BandhuBuy] + 邀请注册链接 + 邀请文案
  71. const shareText = `[BandhuBuy] ${inviteUrl} Your friend invited you to register`
  72. return {
  73. url: inviteUrl,
  74. text: shareText,
  75. }
  76. }
  77. // 检查APP是否安装
  78. function checkAppInstalled(platform: string): boolean {
  79. const appSchemes = {
  80. facebook: { pname: 'com.facebook.katana', scheme: 'fb://' },
  81. whatsapp: { pname: 'com.whatsapp', scheme: 'whatsapp://' },
  82. instagram: { pname: 'com.instagram.android', scheme: 'instagram://' },
  83. twitter: { pname: 'com.twitter.android', scheme: 'twitter://' },
  84. }
  85. const appInfo = appSchemes[platform]
  86. if (!appInfo)
  87. return false
  88. return plus.runtime.isApplicationExist({
  89. pname: appInfo.pname,
  90. action: appInfo.scheme,
  91. })
  92. }
  93. // 打开社交媒体APP分享
  94. function openSocialApp(platform: string) {
  95. const { url, text } = generateInviteShareLink()
  96. // 先复制分享内容到剪贴板
  97. uni.setClipboardData({
  98. data: text,
  99. success: () => {
  100. console.log('分享内容已复制到剪贴板')
  101. },
  102. })
  103. const shareUrls = {
  104. facebook: `fb://facewebmodal/f?href=${encodeURIComponent(url)}`,
  105. whatsapp: `whatsapp://send?text=${encodeURIComponent(text)}`,
  106. instagram: 'instagram://camera', // Instagram不支持直接分享链接,打开相机
  107. twitter: `twitter://post?message=${encodeURIComponent(text)}`,
  108. }
  109. const shareUrl = shareUrls[platform]
  110. if (shareUrl) {
  111. plus.runtime.openURL(shareUrl, (error) => {
  112. console.error('打开APP失败:', error)
  113. toast.info(t('share.appNotInstalled'))
  114. })
  115. }
  116. }
  117. // 统一分享处理方法
  118. function handleShare(platform: string) {
  119. // 检查APP是否安装
  120. if (!checkAppInstalled(platform)) {
  121. toast.info(t('share.appNotInstalled'))
  122. return
  123. }
  124. // 打开对应的社交媒体APP
  125. openSocialApp(platform)
  126. }
  127. onLoad(() => {
  128. // 页面加载时的逻辑
  129. userStore.getUserInfo()
  130. })
  131. </script>
  132. <template>
  133. <view class="share-page min-h-screen bg-white">
  134. <!-- 背景图片区域 -->
  135. <view class="auth-bg-section relative">
  136. <!-- 自定义导航栏 -->
  137. <view :style="{ paddingTop: `${safeAreaInsets?.top}px` }">
  138. <view class="h-88rpx flex items-center px-24rpx">
  139. <wd-icon name="thin-arrow-left" size="32rpx" @click="() => goBack()" />
  140. </view>
  141. </view>
  142. <!-- Logo和标语 -->
  143. <view class="pb-40rpx pt-134rpx text-center">
  144. <view class="mb-20rpx flex flex-col items-center justify-center">
  145. <image src="/static/login-logo.png" class="mb-18rpx h-56rpx w-350.48rpx" />
  146. <view>{{ $t('login.slogan') }}</view>
  147. </view>
  148. </view>
  149. </view>
  150. <!-- 主要内容区域 -->
  151. <view class="flex flex-col px-24rpx">
  152. <!-- 推荐码标题 -->
  153. <view class="mb-10rpx mt-40rpx text-center">
  154. <text class="text-28rpx text-#333 font-medium">
  155. {{ $t('mine.pages.share.referrerCode') }}
  156. </text>
  157. </view>
  158. <!-- 推荐码显示 -->
  159. <view class="mb-44rpx flex items-center justify-center">
  160. <text class="mr-20rpx text-64rpx font-bold tracking-wider">
  161. {{ userInfo.invitedCode }}
  162. </text>
  163. <wd-icon name="file-copy" size="30rpx" color="#757575" @click="copyReferrerCode" />
  164. </view>
  165. <!-- 二维码区域 -->
  166. <view class="mb-60rpx flex justify-center">
  167. <!-- 二维码占位图 -->
  168. <view
  169. style="box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.1);"
  170. class="h-500rpx w-500rpx flex items-center justify-center border-#e5e5e5 rounded-12rpx bg-#f8f8f8"
  171. >
  172. <view class="text-center">
  173. <tki-qrcode
  174. ref="qrcode"
  175. :val="qrcodeConfig.val"
  176. :size="qrcodeConfig.size"
  177. :unit="qrcodeConfig.unit"
  178. :background="qrcodeConfig.background"
  179. :foreground="qrcodeConfig.foreground"
  180. :pdground="qrcodeConfig.pdground"
  181. :icon="qrcodeConfig.icon"
  182. :icon-size="qrcodeConfig.iconsize"
  183. :onval="qrcodeConfig.onval"
  184. :load-make="qrcodeConfig.loadMake"
  185. :show-loading="qrcodeConfig.showLoading"
  186. />
  187. </view>
  188. </view>
  189. </view>
  190. <!-- 分享说明 -->
  191. <view class="mb-60rpx text-center">
  192. <text class="text-28rpx text-#797979 leading-relaxed">
  193. {{ $t('mine.pages.share.description') }}
  194. </text>
  195. </view>
  196. <!-- 社交分享按钮 -->
  197. <view class="flex justify-center gap-50rpx">
  198. <view
  199. v-for="item in socialPlatforms"
  200. :key="item.name"
  201. class="flex flex-col items-center"
  202. @click="handleShare(item.name)"
  203. >
  204. <view class="mb-20rpx">
  205. <image
  206. :src="item.icon"
  207. class="h-80rpx w-80rpx"
  208. mode="aspectFit"
  209. />
  210. </view>
  211. <text class="text-24rpx text-#666 font-medium">
  212. {{ item.label }}
  213. </text>
  214. </view>
  215. </view>
  216. </view>
  217. </view>
  218. </template>
  219. <style lang="scss" scoped>
  220. // 分享页面特有样式
  221. .auth-bg-section {
  222. background-image: url('/static/login-bg.png');
  223. background-size: cover;
  224. background-position: top;
  225. background-repeat: no-repeat;
  226. min-height: 28vh;
  227. }
  228. </style>