123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- const ADType = {
- RewardedVideo: 'RewardedVideo',
- FullScreenVideo: 'FullScreenVideo',
- Interstitial: 'Interstitial'
- }
- const EventType = {
- Load: 'load',
- Close: 'close',
- Error: 'error'
- }
- const EXPIRED_TIME = 1000 * 60 * 30
- const ProviderType = {
- CSJ: 'csj',
- GDT: 'gdt'
- }
- const RETRY_COUNT = 1
- class AdBase {
- constructor (adInstance, options = {}) {
- this._isLoad = false
- this._isLoading = false
- this._isPlaying = false
- this._lastLoadTime = 0
- this._lastError = null
- this._retryCount = 0
- if (options.retry !== undefined) {
- this._retry = options.retry
- } else {
- this._retry = true
- }
- this._loadCallback = null
- this._closeCallback = null
- this._errorCallback = null
- const ad = this._ad = adInstance
- ad.onLoad((e) => {
- this._isLoading = false
- this._isLoad = true
- this._lastLoadTime = Date.now()
- this.onLoad()
- })
- ad.onClose((e) => {
- this._isLoad = false
- this._isPlaying = false
- this.onClose(e)
- })
- ad.onVerify && ad.onVerify((e) => {
- // e.isValid
- })
- ad.onError(({
- code,
- message
- }) => {
- this._isLoading = false
- const data = {
- code: code,
- errMsg: message
- }
- if (this._retry && code === -5008) {
- this._loadAd()
- return
- }
- if (this._retry && this._retryCount < RETRY_COUNT) {
- this._retryCount += 1
- this._loadAd()
- return
- }
- this._lastError = data
- this.onError(data)
- })
- }
- get isExpired () {
- return (this._lastLoadTime !== 0 && (Math.abs(Date.now() - this._lastLoadTime) > EXPIRED_TIME))
- }
- get isLoad () {
- return this._isLoad
- }
- get isLoading () {
- return this._isLoading
- }
- getProvider () {
- return this._ad.getProvider()
- }
- load (onload, onerror) {
- this._loadCallback = onload
- this._errorCallback = onerror
- if (this._isPlaying) {
- onerror && onerror()
- return
- }
- if (this._isLoading) {
- return
- }
- if (this._isLoad) {
- this.onLoad()
- return
- }
- this._retryCount = 0
- this._loadAd()
- }
- show (onclose, onshow) {
- this._closeCallback = onclose
- if (this._isLoading || this._isPlaying || !this._isLoad) {
- return
- }
- if (this._lastError !== null) {
- this.onError(this._lastError)
- return
- }
- const provider = this.getProvider()
- if (provider === ProviderType.CSJ && this.isExpired) {
- if (this._retry) {
- this._loadAd()
- } else {
- this.onError(this._lastError)
- }
- return
- }
- this._isPlaying = true
- this._ad.show()
- onshow && onshow()
- }
- onLoad (e) {
- if (this._loadCallback != null) {
- this._loadCallback()
- }
- }
- onClose (e) {
- if (this._closeCallback != null) {
- this._closeCallback({
- isEnded: e.isEnded
- })
- }
- }
- onError (e) {
- if (this._errorCallback != null) {
- this._errorCallback(e)
- }
- }
- destroy () {
- this._ad.destroy()
- }
- _loadAd () {
- this._isLoad = false
- this._isLoading = true
- this._lastError = null
- this._ad.load()
- }
- }
- class RewardedVideo extends AdBase {
- constructor (options = {}) {
- super(plus.ad.createRewardedVideoAd(options), options)
- }
- }
- class FullScreenVideo extends AdBase {
- constructor (options = {}) {
- super(plus.ad.createFullScreenVideoAd(options), options)
- }
- }
- class Interstitial extends AdBase {
- constructor (options = {}) {
- super(plus.ad.createInterstitialAd(options), options)
- }
- }
- class AdHelper {
- constructor (adType) {
- this._ads = {}
- this._adType = adType
- this._lastWaterfallIndex = -1
- }
- load (options, onload, onerror) {
- if (!options.adpid || this.isBusy(options.adpid)) {
- return
- }
- this.get(options).load(onload, onerror)
- }
- show (options, onload, onerror, onclose, onshow) {
- const ad = this.get(options)
- if (ad.isLoad) {
- this._lastWaterfallIndex = -1
- ad.show((e) => {
- onclose && onclose(e)
- }, () => {
- onshow && onshow()
- })
- } else {
- ad.load(() => {
- this._lastWaterfallIndex = -1
- onload && onload()
- ad.show((e) => {
- onclose && onclose(e)
- }, () => {
- onshow && onshow()
- })
- }, (err) => {
- onerror && onerror(err)
- })
- }
- }
- // 底价预载逻辑
- loadWaterfall (options, onload, onfail, index = 0) {
- const {
- adpid,
- urlCallback
- } = options
- if (!Array.isArray(adpid)) {
- return
- }
- const options2 = {
- adpid: adpid[index],
- urlCallback,
- retry: false
- }
- console.log('ad.loadWaterfall::index=' + index)
- this.load(options2, (res) => {
- this._lastWaterfallIndex = index
- onload(options2)
- }, (err) => {
- index++
- if (index >= adpid.length) {
- onfail(err)
- } else {
- this.loadWaterfall(options, onload, onfail, index)
- }
- })
- }
- // 底价逻辑,失败后下一个,无重试机制
- showWaterfall (options, onload, onfail, onclose, onshow, index = 0) {
- const {
- adpid,
- urlCallback
- } = options
- if (!Array.isArray(adpid)) {
- return
- }
- if (this._lastWaterfallIndex > -1) {
- index = this._lastWaterfallIndex
- }
- const options2 = {
- adpid: adpid[index],
- urlCallback,
- retry: false
- }
- console.log('ad.showWaterfall::index=' + index)
- this.show(options2, () => {
- onload()
- }, (err) => {
- index++
- if (index >= adpid.length) {
- onfail(err)
- } else {
- this.showWaterfall(options, onload, onfail, onclose, onshow, index)
- }
- }, (res) => {
- onclose(res)
- }, () => {
- onshow()
- })
- }
- // 预载底价瀑布流
- preloadWaterfall (options, index = 0, step = 1) {
- if (step === 1) {
- this.loadWaterfall(options, (res) => {
- console.log('preloadWaterfall.success::', res)
- }, (err) => {
- console.log('loadWaterfall.fail', err)
- })
- return
- }
- const {
- adpid,
- urlCallback
- } = options
- for (let i = 0; i < step; i++) {
- if (index < adpid.length) {
- const options2 = {
- adpid: adpid[index],
- urlCallback
- }
- this.loadWaterfall(options2, (res) => {
- console.log('preloadWaterfall.success::', res)
- }, (err) => {
- console.log('loadWaterfall.fail', err)
- this.preloadWaterfall(options, index, step)
- })
- index++
- } else {
- break
- }
- }
- }
- isBusy (adpid) {
- return (this._ads[adpid] && this._ads[adpid].isLoading)
- }
- get (options) {
- const {
- adpid
- } = options
- if (!this._ads[adpid]) {
- this._ads[adpid] = this._createInstance(options)
- }
- return this._ads[adpid]
- }
- getProvider (adpid) {
- if (this._ads[adpid]) {
- return this._ads[adpid].getProvider()
- }
- return null
- }
- remove (adpid) {
- if (this._ads[adpid]) {
- this._ads[adpid].destroy()
- delete this._ads[adpid]
- }
- }
- _createInstance (options) {
- const adType = options.adType || this._adType
- delete options.adType
- let ad = null
- if (adType === ADType.RewardedVideo) {
- ad = new RewardedVideo(options)
- } else if (adType === ADType.FullScreenVideo) {
- ad = new FullScreenVideo(options)
- } else if (adType === ADType.Interstitial) {
- ad = new Interstitial(options, true)
- }
- return ad
- }
- }
- export default {
- props: {
- options: {
- type: [Object, Array],
- default () {
- return {}
- }
- },
- disabled: {
- type: [Boolean, String],
- default: false
- },
- adpid: {
- type: [Number, String, Array],
- default: ''
- },
- preload: {
- type: [Boolean, String],
- default: true
- },
- loadnext: {
- type: [Boolean, String],
- default: false
- },
- urlCallback: {
- type: Object,
- default () {
- return {}
- }
- }
- },
- data () {
- return {
- loading: false,
- errorMessage: null
- }
- },
- created() {
- this.$watch('adpid', (newValue, oldValue) => {
- this._removeInstance(oldValue)
- if (this.preload) {
- this._loadAd()
- }
- })
- // 服务器回调透传参数,仅在创建广告实例时可传递参数,如果发生变化需要重新创建广告实例
- this.$watch('urlCallback', () => {
- this._removeInstance()
- })
-
- this._adHelper = new AdHelper(this.adType)
-
- setTimeout(() => {
- if (this.preload) {
- this._loadAd()
- }
- }, 100)
- },
- methods: {
- load () {
- if (this.isLoading) {
- return
- }
- this._startLoading()
- const invoke = this._isWaterfall() ? 'loadWaterfall' : 'load'
- this._adHelper[invoke](this._getAdOptions(), () => {
- this._onLoad()
- }, (err) => {
- this._onLoadFail(err)
- })
- },
- show () {
- if (this.isLoading) {
- return
- }
- this._startLoading()
- const invoke = this._isWaterfall() ? 'showWaterfall' : 'show'
- this._adHelper[invoke](this._getAdOptions(), () => {
- this._onLoad()
- }, (err) => {
- this._onLoadFail(err)
- }, (res) => {
- this._dispatchEvent(EventType.Close, res)
- if (this.loadnext) {
- this.load()
- }
- }, () => {
- // show
- this.loading = false
- })
- },
- getProvider () {
- if (Array.isArray(this.adpid)) {
- return null
- }
- return this._adHelper.getProvider(this.adpid)
- },
- _loadAd () {
- if (this._canCreateAd()) {
- this.load()
- }
- },
- _onclick () {
- if (!this.disabled) {
- this.show()
- }
- },
- _getAdOptions () {
- return {
- adpid: this.adpid,
- urlCallback: this.urlCallback
- }
- },
- _isWaterfall () {
- return (Array.isArray(this.adpid) && this.adpid.length > 0)
- },
- _canCreateAd () {
- let result = false
- if (Array.isArray(this.adpid) && this.adpid.length > 0) {
- result = true
- } else if (typeof this.adpid === 'string' && this.adpid.length > 0) {
- result = true
- } else if (typeof this.adpid === 'number') {
- result = true
- }
- return result
- },
- _removeInstance (adpid) {
- const id = adpid || this.adpid
- if (Array.isArray(id)) {
- id.forEach((item) => {
- this._adHelper.remove(item)
- })
- } else if (id) {
- this._adHelper.remove(id)
- }
- },
- _startLoading () {
- this.loading = true
- this.errorMessage = null
- },
- _onLoad () {
- this.loading = false
- this._dispatchEvent(EventType.Load, {})
- },
- _onLoadFail (err) {
- this.loading = false
- this.errorMessage = JSON.stringify(err)
- this._dispatchEvent(EventType.Error, err)
- },
- _dispatchEvent (type, data) {
- this.$emit(type, {
- detail: data
- })
- }
- }
- }
|