典型应用场景:
支付成功后,对支付结果进行语音播报:xxx 已支付 100 元。
已有部分解决方案:
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/database/realtime.html
云数据库支持数据库数据变化监听,可以返回新增的订单记录。
在监听到订单后,需要调用txttospeech播放语音,但是语音播放是有处理时间的,比如播放需要2秒,那么就会出现同一时间播放多条语音。如下代码:
我的想法是对data中的orders进行监听,处理一个去拿一个,但是要阻塞监听。
const watcher = db.collection('order')
// 按 progress 降序
.orderBy('modified', 'desc')
// 取按 orderBy 排序之后的前 10 个
// .limit(10)
.where({
sid: sid,
modified: _.gt(new Date()),
status: 'DAIZHIFU'
})
.watch({
onChange: function (snapshot) {
if (snapshot.type === 'init') {
console.log('data type : ' + snapshot.type)
} else {
let hasNewOrder = false
const orders = _this.data.orders
var plugin = requirePlugin("WechatSI")
for (const docChange of snapshot.docChanges) {
switch (docChange.queueType) {
case 'enqueue': {
console.log("new order wxOrder = " + docChange.doc.wxOrder)
hasNewOrder = true
orders.unshift(docChange.doc)
console.log('orders : ', orders)
var sfname = docChange.doc.sfname
var price = docChange.doc.price // 分
const fenStr = '00' + Number.parseInt(price.toString()).toString()
var priceYuan = Number.parseFloat(fenStr.replace(/^(\d+?)(\d{2})$/g, '$1.$2'))
var text = sfname + "收款" + priceYuan + "元"
// let manager = plugin.getRecordRecognitionManager()
plugin.textToSpeech({
lang: "zh_CN",
tts: true,
content: text,
success: function (res) {
console.log("succ tts", res.filename)
// 播放声音
var mp3 = res.filename
var audio = wx.createInnerAudioContext()
audio.src = mp3
audio.autoplay = true
audio.onPlay(() => {
console.log('开始播放')
})
audio.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
})
},
fail: function (res) {
console.log("fail tts", res)
wx.showModal({
showCancel: false,
title: 'TTS Fail',
content: JSON.stringify(res)
})
}
})
}
}
}
_this.setData({
orders: orders,
hasNewOrder: hasNewOrder
})
if (_this.data.hasNewMessage) {
_this.scrollToBottom()
}
}
},
onError: function (err) {
console.error('the watch closed because of error', err)
wx.showModal({
showCancel: false,
title: '提示',
content: JSON.stringify(err)
})
}
})
onChange里不播放,仅把结果放在一个队列里;
另一个进程轮询处理这个队列,处理完一条清除,再处理下一条;