@tencentcloud/ai-desk-customer-uniapp
Version:
uni-app Vue2/Vue3 UIKit for AI Desk
248 lines (242 loc) • 6.38 kB
JavaScript
/**
* @fileoverview 递归子组件,用于显示节点树
*/
Component({
data: {
ctrl: {}, // 控制信号
// #ifdef MP-WEIXIN
isiOS: wx.getSystemInfoSync().system.includes('iOS')
// #endif
},
properties: {
childs: Array, // 子节点列表
opts: Array // 设置 [是否开启懒加载, 加载中占位图, 错误占位图, 是否使用长按菜单]
},
options: {
addGlobalClass: true
},
// #ifndef MP-TOUTIAO
attached () {
// #ifndef MP-ALIPAY
this.triggerEvent('add', this, {
bubbles: true,
composed: true
})
// #endif
// #ifdef MP-ALIPAY
this.props.onAdd(this)
// #endif
},
// #endif
methods: {
noop () { },
/**
* @description 获取标签
* @param {String} path 路径
*/
getNode (path) {
try {
const nums = path.split('_')
let node = this.properties.childs[nums[0]]
for (let i = 1; i < nums.length; i++) {
node = node.children[nums[i]]
}
return node
} catch {
return {
text: '',
attrs: {},
children: []
}
}
},
/**
* @description 播放视频事件
* @param {Event} e
*/
play (e) {
const i = e.target.dataset.i
const node = this.getNode(i)
this.root.triggerEvent('play', {
source: node.name,
attrs: {
...node.attrs,
src: node.src[this.data.ctrl[i] || 0]
}
})
if (this.root.properties.pauseVideo) {
let flag = false
const id = e.target.id
for (let i = this.root._videos.length; i--;) {
if (this.root._videos[i].id === id) {
flag = true
} else {
this.root._videos[i].pause() // 自动暂停其他视频
}
}
// 将自己加入列表
if (!flag) {
const ctx = wx.createVideoContext(id
// #ifndef MP-BAIDU
, this
// #endif
)
ctx.id = id
if (this.root.playbackRate) {
ctx.playbackRate(this.root.playbackRate)
}
this.root._videos.push(ctx)
}
}
},
/**
* @description 图片点击事件
* @param {Event} e
*/
imgTap (e) {
const node = this.getNode(e.target.dataset.i)
// 父级中有链接
if (node.a) return this.linkTap(node.a)
if (node.attrs.ignore) return
this.root.triggerEvent('imgtap', node.attrs)
if (this.root.properties.previewImg) {
const current =
// #ifndef MP-ALIPAY
this.root.imgList[node.i]
// #endif
// #ifdef MP-ALIPAY
node.i // eslint-disable-line
// #endif
// 自动预览图片
wx.previewImage({
// #ifdef MP-WEIXIN
showmenu: this.root.properties.showImgMenu,
// #endif
// #ifdef MP-ALIPAY
enablesavephoto: this.root.properties.showImgMenu,
enableShowPhotoDownload: this.root.properties.showImgMenu,
// #endif
current,
urls: this.root.imgList
})
}
},
/**
* @description 图片加载完成事件
* @param {Event} e
*/
imgLoad (e) {
const i = e.target.dataset.i
const node = this.getNode(i)
let val
if (!node.w) {
val = e.detail.width
} else if ((this.properties.opts[1] && !this.data.ctrl[i]) || this.data.ctrl[i] === -1) {
// 加载完毕,取消加载中占位图
val = 1
}
if (val
// #ifdef MP-TOUTIAO
&& val !== this.data.ctrl[i] // eslint-disable-line
// #endif
) {
this.setData({
['ctrl.' + i]: val
})
}
this.checkReady()
},
/**
* @description 检查是否所有图片加载完毕
*/
checkReady () {
if (!this.root.properties.lazyLoad) {
this.root.imgList._unloadimgs -= 1
if (!this.root.imgList._unloadimgs) {
setTimeout(() => {
this.root.getRect().then(rect => {
this.root.triggerEvent('ready', rect)
}).catch(() => {
this.root.triggerEvent('ready', {})
})
}, 350)
}
}
},
/**
* @description 链接点击事件
* @param {Event} e
*/
linkTap (e) {
const node = e.currentTarget ? this.getNode(e.currentTarget.dataset.i) : {}
const attrs = node.attrs || e
const href = attrs.href
this.root.triggerEvent('linktap', Object.assign({
innerText: this.root.getText(node.children || []) // 链接内的文本内容
}, attrs))
if (href) {
if (href[0] === '#') {
// 跳转锚点
this.root.navigateTo(href.substring(1)).catch(() => { })
} else if (href.split('?')[0].includes('://')) {
// 复制外部链接
if (this.root.properties.copyLink) {
wx.setClipboardData({
data: href,
success: () =>
wx.showToast({
title: '链接已复制'
})
})
}
} else {
// 跳转页面
wx.navigateTo({
url: href,
fail () {
wx.switchTab({
url: href,
fail () { }
})
}
})
}
}
},
/**
* @description 错误事件
* @param {Event} e
*/
mediaError (e) {
const i = e.target.dataset.i
const node = this.getNode(i)
if (node.name === 'video' || node.name === 'audio') {
// 加载其他源
let index = (this.data.ctrl[i] || 0) + 1
if (index > node.src.length) {
index = 0
}
if (index < node.src.length) {
return this.setData({
['ctrl.' + i]: index
})
}
} else if (node.name === 'img') {
// 显示错误占位图
if (this.properties.opts[2]) {
this.setData({
['ctrl.' + i]: -1
})
}
this.checkReady()
}
if (this.root) {
this.root.triggerEvent('error', {
source: node.name,
attrs: node.attrs,
errMsg: e.detail.errMsg
})
}
}
}
})