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

231 lines
6.9 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.isWatchingAd) {
  107. return
  108. }
  109. // 保存当前的回调方法,避免覆盖组件中已定义的方法
  110. const originalOnAdWatchComplete = this.onAdWatchComplete
  111. const originalOnAdWatchCancel = this.onAdWatchCancel
  112. const originalOnAdError = this.onAdError
  113. // 临时设置回调方法
  114. if (options.onSuccess) {
  115. this.tempOnAdWatchComplete = options.onSuccess
  116. }
  117. if (options.onCancel) {
  118. this.tempOnAdWatchCancel = options.onCancel
  119. }
  120. if (options.onError) {
  121. this.tempOnAdError = options.onError
  122. }
  123. // #ifdef MP-WEIXIN
  124. if (this.rewardedVideoAd) {
  125. this.isWatchingAd = true
  126. this.rewardedVideoAd.show().catch(() => {
  127. // 广告显示失败,重新加载
  128. this.rewardedVideoAd.load().then(() => {
  129. return this.rewardedVideoAd.show()
  130. }).catch((err) => {
  131. console.log('激励视频广告显示失败', err)
  132. this.isWatchingAd = false
  133. // 显示失败处理
  134. const title = options.fallbackTitle || '广告加载失败'
  135. const content = options.fallbackContent || '无法加载广告,是否继续操作?'
  136. uni.showModal({
  137. title: title,
  138. content: content,
  139. success: (res) => {
  140. if (res.confirm) {
  141. // 用户确认继续,调用成功回调
  142. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  143. this.tempOnAdWatchComplete()
  144. } else if (originalOnAdWatchComplete && typeof originalOnAdWatchComplete === 'function') {
  145. originalOnAdWatchComplete.call(this)
  146. }
  147. }
  148. // 恢复原始回调方法
  149. this.onAdWatchComplete = originalOnAdWatchComplete
  150. this.onAdWatchCancel = originalOnAdWatchCancel
  151. this.onAdError = originalOnAdError
  152. }
  153. })
  154. })
  155. })
  156. } else {
  157. // 没有广告实例,直接调用成功回调
  158. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  159. this.tempOnAdWatchComplete()
  160. } else if (originalOnAdWatchComplete && typeof originalOnAdWatchComplete === 'function') {
  161. originalOnAdWatchComplete.call(this)
  162. }
  163. // 恢复原始回调方法
  164. this.onAdWatchComplete = originalOnAdWatchComplete
  165. this.onAdWatchCancel = originalOnAdWatchCancel
  166. this.onAdError = originalOnAdError
  167. }
  168. // #endif
  169. // #ifndef MP-WEIXIN
  170. // 非微信小程序环境,直接调用成功回调
  171. if (this.tempOnAdWatchComplete && typeof this.tempOnAdWatchComplete === 'function') {
  172. this.tempOnAdWatchComplete()
  173. } else if (originalOnAdWatchComplete && typeof originalOnAdWatchComplete === 'function') {
  174. originalOnAdWatchComplete.call(this)
  175. }
  176. // 恢复原始回调方法
  177. this.onAdWatchComplete = originalOnAdWatchComplete
  178. this.onAdWatchCancel = originalOnAdWatchCancel
  179. this.onAdError = originalOnAdError
  180. // #endif
  181. },
  182. /**
  183. * 重新加载广告
  184. */
  185. reloadAd() {
  186. // #ifdef MP-WEIXIN
  187. if (this.rewardedVideoAd) {
  188. this.rewardedVideoAd.load()
  189. }
  190. // #endif
  191. },
  192. /**
  193. * 销毁广告实例
  194. */
  195. destroyAd() {
  196. // #ifdef MP-WEIXIN
  197. if (this.rewardedVideoAd) {
  198. this.rewardedVideoAd.destroy()
  199. this.rewardedVideoAd = null
  200. }
  201. // #endif
  202. }
  203. },
  204. // 组件销毁时清理广告实例
  205. beforeDestroy() {
  206. this.destroyAd()
  207. },
  208. // uni-app 生命周期
  209. onUnload() {
  210. this.destroyAd()
  211. }
  212. }