瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
7.2 KiB

  1. /**
  2. * 激励视频广告混入
  3. * 提供激励视频广告的通用功能
  4. */
  5. export default {
  6. data() {
  7. return {
  8. rewardedRecordConfig: {
  9. category: 3, // 分类 3激励视频
  10. type: 0, // 类型 0帖子-1租房-2工作-3景点-4美食-5活动-6人找车-7车找人-8文章-9群聊-10抽奖
  11. formId: '', // 目标对象ID
  12. },
  13. // 视频广告相关
  14. rewardedVideoAd: null, // 激励视频广告实例
  15. isAdLoaded: false, // 广告是否已加载
  16. isWatchingAd: false, // 是否正在观看广告
  17. adUnitId: 'adunit-3b232fe9e10e8744' // 广告位ID,需要替换为实际的广告位ID
  18. }
  19. },
  20. mounted() {
  21. this.initRewardedVideoAd()
  22. },
  23. methods: {
  24. /**
  25. * 初始化激励视频广告
  26. */
  27. initRewardedVideoAd() {
  28. // #ifdef MP-WEIXIN
  29. if (wx.createRewardedVideoAd) {
  30. this.rewardedVideoAd = wx.createRewardedVideoAd({
  31. adUnitId: this.adUnitId
  32. })
  33. // 监听广告加载成功
  34. this.rewardedVideoAd.onLoad(() => {
  35. console.log('激励视频广告加载成功')
  36. this.isAdLoaded = true
  37. // 调用子组件的回调方法(如果存在)
  38. if (this.onAdLoaded && typeof this.onAdLoaded === 'function') {
  39. this.onAdLoaded()
  40. }
  41. })
  42. // 监听广告加载失败
  43. this.rewardedVideoAd.onError((err) => {
  44. console.log('激励视频广告加载失败', err)
  45. this.isAdLoaded = false
  46. // 调用子组件的回调方法(如果存在)
  47. if (this.onAdError && typeof this.onAdError === 'function') {
  48. this.onAdError(err)
  49. }
  50. })
  51. // 监听广告关闭
  52. this.rewardedVideoAd.onClose((res) => {
  53. this.isWatchingAd = false
  54. if (res && res.isEnded) {
  55. // 用户看完了广告
  56. console.log('用户看完广告')
  57. // 调用临时回调方法或组件中定义的方法
  58. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  59. this.tempOnAdWatchComplete()
  60. } else if (this.onAdWatchComplete && typeof this.onAdWatchComplete === 'function') {
  61. this.onAdWatchComplete()
  62. }
  63. } else {
  64. // 用户中途关闭了广告
  65. console.log('用户中途关闭广告')
  66. // 调用临时回调方法或组件中定义的方法
  67. if (this.tempOnAdWatchCancel && typeof this.tempOnAdWatchCancel === 'function') {
  68. this.tempOnAdWatchCancel()
  69. } else if (this.onAdWatchCancel && typeof this.onAdWatchCancel === 'function') {
  70. this.onAdWatchCancel()
  71. } else {
  72. // 默认提示
  73. uni.showToast({
  74. title: '请观看完整广告',
  75. icon: 'none'
  76. })
  77. }
  78. }
  79. this.$api('addBrowseRecord', {
  80. ...this.rewardedRecordConfig,
  81. complete: (res && res.isEnded) ? 'Y' : 'N'
  82. })
  83. // 清理临时回调方法
  84. this.tempOnAdWatchComplete = null
  85. this.tempOnAdWatchCancel = null
  86. this.tempOnAdError = null
  87. })
  88. // 预加载广告
  89. this.rewardedVideoAd.load()
  90. } else {
  91. console.log('当前环境不支持激励视频广告')
  92. }
  93. // #endif
  94. },
  95. /**
  96. * 显示激励视频广告
  97. * @param {Object} options 配置选项
  98. * @param {Function} options.onSuccess 观看完成后的回调
  99. * @param {Function} options.onCancel 取消观看的回调
  100. * @param {Function} options.onError 广告加载失败的回调
  101. * @param {String} options.fallbackTitle 广告加载失败时的弹窗标题
  102. * @param {String} options.fallbackContent 广告加载失败时的弹窗内容
  103. */
  104. showRewardedVideoAd(options = {}) {
  105. // 检查用户是否已登录
  106. if (!this.userInfo || !this.userInfo.id) {
  107. console.log('用户未登录,跳转到登录页面')
  108. // 使用utils中的toLogin方法跳转到登录页面
  109. this.$utils.toLogin()
  110. return
  111. }
  112. // 如果正在观看广告,直接返回
  113. if (this.isWatchingAd) {
  114. return
  115. }
  116. // 保存当前的回调方法,避免覆盖组件中已定义的方法
  117. const originalOnAdWatchComplete = this.onAdWatchComplete
  118. const originalOnAdWatchCancel = this.onAdWatchCancel
  119. const originalOnAdError = this.onAdError
  120. // 临时设置回调方法
  121. if (options.onSuccess) {
  122. this.tempOnAdWatchComplete = options.onSuccess
  123. }
  124. if (options.onCancel) {
  125. this.tempOnAdWatchCancel = options.onCancel
  126. }
  127. if (options.onError) {
  128. this.tempOnAdError = options.onError
  129. }
  130. // #ifdef MP-WEIXIN
  131. if (this.rewardedVideoAd) {
  132. this.isWatchingAd = true
  133. this.rewardedVideoAd.show().catch(() => {
  134. // 广告显示失败,重新加载
  135. this.rewardedVideoAd.load().then(() => {
  136. return this.rewardedVideoAd.show()
  137. }).catch((err) => {
  138. console.log('激励视频广告显示失败', err)
  139. this.isWatchingAd = false
  140. // 显示失败处理
  141. const title = options.fallbackTitle || '广告加载失败'
  142. const content = options.fallbackContent || '无法加载广告,是否继续操作?'
  143. uni.showModal({
  144. title: title,
  145. content: content,
  146. success: (res) => {
  147. if (res.confirm) {
  148. // 用户确认继续,调用成功回调
  149. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  150. this.tempOnAdWatchComplete()
  151. } else if (originalOnAdWatchComplete && typeof originalOnAdWatchComplete === 'function') {
  152. originalOnAdWatchComplete.call(this)
  153. }
  154. }
  155. // 恢复原始回调方法
  156. this.onAdWatchComplete = originalOnAdWatchComplete
  157. this.onAdWatchCancel = originalOnAdWatchCancel
  158. this.onAdError = originalOnAdError
  159. }
  160. })
  161. })
  162. })
  163. } else {
  164. // 没有广告实例,直接调用成功回调
  165. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  166. this.tempOnAdWatchComplete()
  167. } else if (originalOnAdWatchComplete && typeof originalOnAdWatchComplete === 'function') {
  168. originalOnAdWatchComplete.call(this)
  169. }
  170. // 恢复原始回调方法
  171. this.onAdWatchComplete = originalOnAdWatchComplete
  172. this.onAdWatchCancel = originalOnAdWatchCancel
  173. this.onAdError = originalOnAdError
  174. }
  175. // #endif
  176. // #ifndef MP-WEIXIN
  177. // 非微信小程序环境,直接调用成功回调
  178. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  179. this.tempOnAdWatchComplete()
  180. } else if (originalOnAdWatchComplete && typeof originalOnAdWatchComplete === 'function') {
  181. originalOnAdWatchComplete.call(this)
  182. }
  183. // 恢复原始回调方法
  184. this.onAdWatchComplete = originalOnAdWatchComplete
  185. this.onAdWatchCancel = originalOnAdWatchCancel
  186. this.onAdError = originalOnAdError
  187. // #endif
  188. },
  189. /**
  190. * 重新加载广告
  191. */
  192. reloadAd() {
  193. // #ifdef MP-WEIXIN
  194. if (this.rewardedVideoAd) {
  195. this.rewardedVideoAd.load()
  196. }
  197. // #endif
  198. },
  199. /**
  200. * 销毁广告实例
  201. */
  202. destroyAd() {
  203. // #ifdef MP-WEIXIN
  204. if (this.rewardedVideoAd) {
  205. this.rewardedVideoAd.destroy()
  206. this.rewardedVideoAd = null
  207. }
  208. // #endif
  209. }
  210. },
  211. // 组件销毁时清理广告实例
  212. beforeDestroy() {
  213. this.destroyAd()
  214. },
  215. // uni-app 生命周期
  216. onUnload() {
  217. this.destroyAd()
  218. }
  219. }