share-mixin.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * share-mixin — 统一分享逻辑
  3. * 处理:邀请码获取、分享配置、自动绑定邀请码
  4. *
  5. * 使用方式:
  6. * mixins: [shareMixin],
  7. * mounted/after data load:
  8. * this.setShareInfo('推荐阅读: ' + title, '/pages/article-center/article-detail?id=' + id)
  9. */
  10. import { getReferralCode, bindReferralIfNotSelf, extractReferralCode } from '../utils/api.js'
  11. export default {
  12. data() {
  13. return {
  14. referralCode: '',
  15. shareTitle: '',
  16. sharePath: ''
  17. }
  18. },
  19. onLoad(options) {
  20. // 自动绑定:从分享链接进入时,绑定推荐人(推荐码统一为 refCode,兼容老 inviteCode 链接)
  21. if (options) {
  22. var code = options.refCode || options.inviteCode
  23. if (code) {
  24. this.autoBindInviteCode(code)
  25. }
  26. }
  27. },
  28. methods: {
  29. /**
  30. * 设置分享信息(由各页面在数据加载完成后调用)
  31. */
  32. setShareInfo(title, path) {
  33. this.shareTitle = title
  34. this.sharePath = path
  35. this.loadReferralCode()
  36. },
  37. /**
  38. * 获取自己的邀请码
  39. */
  40. async loadReferralCode() {
  41. if (this.referralCode) return
  42. // 未登录时不请求邀请码(避免 500 报错弹窗和 401 跳转)
  43. if (!uni.getStorageSync('token')) return
  44. try {
  45. var res = await getReferralCode()
  46. this.referralCode = extractReferralCode(res)
  47. } catch (e) {
  48. console.log('获取邀请码失败', e)
  49. }
  50. },
  51. /**
  52. * 自动绑定分享者的邀请码
  53. * 规则:如果用户已有邀请人,则忽略此邀请码
  54. */
  55. async autoBindInviteCode(code) {
  56. // 未登录时存 storage,登录后由 login 页面处理(推荐码统一为 refCode)
  57. if (!uni.getStorageSync('token')) {
  58. uni.setStorageSync('refCode', code)
  59. return
  60. }
  61. // 已绑定过则跳过
  62. var bound = uni.getStorageSync('boundInviteCode')
  63. if (bound === code) return
  64. try {
  65. var res = await bindReferralIfNotSelf(code)
  66. if (res && res.code === 200) {
  67. uni.setStorageSync('boundInviteCode', code)
  68. console.log('邀请码绑定成功', code)
  69. }
  70. } catch (e) {
  71. // 后端已绑定(code=500 message=已绑定推荐人)→ 记录防重,避免每次进入重复请求/重复提示
  72. if (e && e.code !== undefined && e.code !== 401) {
  73. uni.setStorageSync('boundInviteCode', code)
  74. console.log('邀请码绑定失败(业务拒绝,已防重)', code, e.message || '')
  75. } else {
  76. console.log('邀请码绑定失败(网络/登录态)', e)
  77. }
  78. }
  79. },
  80. /**
  81. * 拼接完整分享路径
  82. */
  83. getSharePath() {
  84. if (!this.sharePath) return ''
  85. if (this.referralCode) {
  86. var sep = this.sharePath.indexOf('?') === -1 ? '?' : '&'
  87. return this.sharePath + sep + 'refCode=' + this.referralCode
  88. }
  89. return this.sharePath
  90. },
  91. /**
  92. * 分享按钮点击(用于统计等)
  93. */
  94. onShareTap() {
  95. console.log('分享按钮点击')
  96. }
  97. },
  98. onShareAppMessage() {
  99. if (!this.shareTitle || !this.sharePath) {
  100. return {
  101. title: '浠艾福 — 给全家的一站式幸福提案',
  102. path: '/pages/index-home/index'
  103. }
  104. }
  105. return {
  106. title: this.shareTitle,
  107. path: this.getSharePath(),
  108. imageUrl: ''
  109. }
  110. },
  111. /**
  112. * 分享到朋友圈(微信基础库 2.11.3+,仅非游戏类小程序支持)
  113. * 前提:该页面已定义 onShareAppMessage(已满足)
  114. * 注意:单页模式下页面无登录态,详情接口需在 JwtInterceptor 的公开路径中
  115. */
  116. onShareTimeline() {
  117. var path = this.getSharePath()
  118. var query = ''
  119. var qi = path.indexOf('?')
  120. if (qi !== -1) query = path.substring(qi + 1)
  121. return {
  122. title: this.shareTitle || '浠艾福 — 给全家的一站式幸福提案',
  123. query: query
  124. }
  125. }
  126. }