recommend-mixin.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /**
  2. * 推荐系统 Mixin — 为维度页面提供个性化推荐加载与行为追踪
  3. *
  4. * 用法:
  5. * import recommendMixin from '../../mixins/recommend-mixin'
  6. * export default {
  7. * mixins: [recommendMixin],
  8. * methods: {
  9. * loadDimensionData: function() {
  10. * this.loadRecommendations('action') // 传入当前维度代码
  11. * }
  12. * }
  13. * }
  14. *
  15. * 模板:
  16. * <RecommendedSection
  17. * v-if="recommendItems.length > 0"
  18. * :items="recommendItems"
  19. * :hasMore="recommendHasMore"
  20. * @itemClick="onRecommendItemClick"
  21. * @more="$emit('more')" />
  22. */
  23. import { getRecommendList, trackRecommendAction } from '../utils/api'
  24. var recommendMixin = {
  25. data: function() {
  26. return {
  27. recommendItems: [],
  28. recommendHasMore: false,
  29. _recommendDimension: null
  30. }
  31. },
  32. methods: {
  33. /**
  34. * 加载个性化推荐列表
  35. * @param {String} dimensionCode 维度代码 body/mind/wisdom/action/wealth
  36. * @param {Number} limit 推荐数量
  37. */
  38. loadRecommendations: function(dimensionCode, limit) {
  39. limit = limit || 6
  40. this._recommendDimension = dimensionCode
  41. var self = this
  42. getRecommendList({
  43. dimensionCode: dimensionCode,
  44. size: limit
  45. }).then(function(res) {
  46. if (res.code === 200 && res.data && res.data.items) {
  47. self.recommendItems = res.data.items || []
  48. self.recommendHasMore = res.data.hasMore || false
  49. }
  50. }).catch(function() {
  51. // 静默失败,不阻塞页面
  52. })
  53. },
  54. /**
  55. * 推荐项点击处理 — 跳转 + 行为追踪
  56. */
  57. onRecommendItemClick: function(item) {
  58. if (!item) return
  59. // 追踪点击行为
  60. this._trackRecommend(item, 'click')
  61. // 根据内容类型跳转
  62. this._navigateToRecommend(item)
  63. },
  64. /**
  65. * 内部:追踪推荐行为
  66. */
  67. _trackRecommend: function(item, action) {
  68. trackRecommendAction({
  69. contentType: item.contentType,
  70. contentId: item.id,
  71. action: action
  72. }).catch(function() {
  73. // 静默
  74. })
  75. },
  76. /**
  77. * 内部:根据内容类型导航
  78. */
  79. _navigateToRecommend: function(item) {
  80. var url = ''
  81. switch (item.contentType) {
  82. case 'article':
  83. url = '/pages/article-center/article-detail/article-detail?id=' + item.id
  84. break
  85. case 'task':
  86. url = '/pages/tasks/task-detail/task-detail?id=' + item.id
  87. break
  88. case 'product':
  89. url = '/pages/shop/product-detail/product-detail?id=' + item.id
  90. break
  91. case 'activity':
  92. url = '/pages/activity/activity-detail/activity-detail?id=' + item.id
  93. break
  94. default:
  95. return
  96. }
  97. if (url) {
  98. uni.navigateTo({ url: url })
  99. }
  100. }
  101. },
  102. /**
  103. * 页面显示时展示推荐内容(曝光追踪)
  104. */
  105. onShow: function() {
  106. if (this.recommendItems && this.recommendItems.length > 0) {
  107. var self = this
  108. // 只追踪前3条曝光(避免过多请求)
  109. var showItems = this.recommendItems.slice(0, 3)
  110. showItems.forEach(function(item) {
  111. self._trackRecommend(item, 'show')
  112. })
  113. }
  114. }
  115. }
  116. export default recommendMixin