Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

100 linhas
2.8 KiB

  1. import { inviteApi } from '@/api/index.js'
  2. import { useUserStore } from '@/store/user.js'
  3. const DEFAULT_SHARE = {
  4. title: 'AI在线|开箱即用的 AI 工具箱',
  5. imageUrl: '',
  6. path: '/pages/toolbox/toolbox'
  7. }
  8. const shareState = {
  9. loaded: false,
  10. loading: null,
  11. token: '',
  12. share: {},
  13. config: {}
  14. }
  15. function appendQuery(path, query = {}) {
  16. let nextPath = path || DEFAULT_SHARE.path
  17. const pairs = Object.keys(query)
  18. .filter((key) => query[key] !== undefined && query[key] !== null && query[key] !== '')
  19. .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
  20. if (!pairs.length) return nextPath
  21. nextPath += nextPath.includes('?') ? '&' : '?'
  22. return nextPath + pairs.join('&')
  23. }
  24. function getInviteCode() {
  25. const userStore = useUserStore()
  26. userStore.restore()
  27. const user = userStore.userInfo || {}
  28. return user.open_id || user.user_open_id || user.invite_code || uni.getStorageSync('open_id') || ''
  29. }
  30. export function getInviteSharePath(options = {}) {
  31. const inviteCode = getInviteCode()
  32. // 与邀请好友页保持同一落地逻辑:统一进入邀请落地页。
  33. // 未登录时 invite_code 为空,好友仍能进入活动说明;登录用户会携带自己的 open_id。
  34. const path = `/pages/invite/landing?invite_code=${encodeURIComponent(inviteCode)}`
  35. return appendQuery(path, { source: options.source })
  36. }
  37. export async function preloadInviteShare() {
  38. const userStore = useUserStore()
  39. userStore.restore()
  40. const currentToken = userStore.token || ''
  41. if (!currentToken) {
  42. shareState.loaded = true
  43. shareState.token = ''
  44. shareState.share = {}
  45. shareState.config = {}
  46. return shareState
  47. }
  48. if (shareState.loaded && shareState.token === currentToken) return shareState
  49. if (shareState.loading) return shareState.loading
  50. shareState.loading = inviteApi.getMy({}, { authSilent: true })
  51. .then((res) => {
  52. const data = res.data || {}
  53. shareState.share = data.share || {}
  54. shareState.config = data.config || {}
  55. shareState.token = currentToken
  56. shareState.loaded = true
  57. return shareState
  58. })
  59. .catch(() => {
  60. shareState.loaded = true
  61. return shareState
  62. })
  63. .finally(() => {
  64. shareState.loading = null
  65. })
  66. return shareState.loading
  67. }
  68. export function buildShareOptions(options = {}) {
  69. const share = shareState.share || {}
  70. const config = shareState.config || {}
  71. const path = appendQuery(
  72. options.path || share.path || getInviteSharePath(),
  73. { source: options.source }
  74. )
  75. return {
  76. title: options.title || share.title || config.share_title || DEFAULT_SHARE.title,
  77. path,
  78. imageUrl: options.imageUrl || share.image || config.share_image || DEFAULT_SHARE.imageUrl
  79. }
  80. }
  81. export function showPageShareMenu() {
  82. preloadInviteShare()
  83. try {
  84. uni.showShareMenu({ withShareTicket: true })
  85. } catch (e) {}
  86. }