瑶都万能墙
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.

220 lines
6.5 KiB

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