小程序端
将下面代码放在mixin里面
export default {
methods:{
saveFormIds() {
/*
* 调保存接口有两种情况:
* 1: 退出小程序
* 2: formID数组达到一定数量(此处设为30个)
*/
console.log('saveFormIds')
let formIds=this.$storage('formIds')
if(formIds.length>0) {
this.$storage('formIds', [])
}
console.log('formIds:',formIds)
if(formIds.length>0) {
this.$api.saveFormIds({
formIds:formIds
}).then(res=>{
console.log(res)
}).catch(err=>{
console.error(err)
})
}
},
dealFormIds(formId) {
console.log('dealFormIds')
console.log('click formId:',formId)
// 开发工具上点击按钮生成的mock FormId不收集
if(!formId||formId==='the formId is a mock one') return
let formIds=this.$storage('formIds')
let expire=parseInt(newDate().getTime()/1000)+604800// 计算七天后过期的时间戳
if(!formIds) formIds=[]
let item={
formId:formId,
expire:expire
}
formIds.push(item)
this.$storage('formIds',formIds)
// formID 长度大于30时,调用接口保存formId
if(formIds.length>=30) {
console.log('长度大于30啦啦啦啦啦啦啦啦啦啦啦')
this.saveFormIds()
}
}
}
}
app.js里面引入全局mixin:
import mixin from '@/mixin'
Vue.mixin(mixin)
小程序端formId收集示例(一般加在按钮上面):
<form report-submit='true'
@submit="go2($event)">
<button hover-class="none"
formType="submit">
button内容
</button>
</form>
// go2方法
go2(type,event) {
let formId=event.target.formId
// 存储formId
this.dealFormIds(formId)
}
在关闭小程序页面或者formId收集到30个的时候调用保存formId的接口
onHide() {
this.saveFormIds()
console.log('app hide')
}
node端(node+mongodb)
1.保存formId
// 保存formId
static async saveFormId(ctx) {
let params=ctx.request.body
console.log('==================保存formId==================')
console.log('params',params)
let userId=await ctx.getUserId()
if(!userId) {
return ctx.sendError('000002','用户未登录')
}
// 判断是否存在这个用户的记录
let check=await TemplateMsg.findOne({userId:userId})
let update
let add
if(check) {
// 存在,更新
update=await TemplateMsg.updateOne({userId:userId},
{
$push:{
formIdList:{
$each:params.formIds
}
}
})
}else{
// 不存在,添加
let item={
userId:userId,
formIdList:params.formIds
}
add=await TemplateMsg(item).save()
}
if(update&&update.ok===1||add) {
return ctx.send(null,'保存formId成功')
}else{
return ctx.sendError('000002','保存formId失败')
}
}
2.发送模板消息
const sendTemplateMsg=async(template_id,
wx_url,
data,
touserOpenId,
userId)=>{
// 获取并判断token是否失效
let token=await getToken()
// 获取有效的formId
let formId=await getFormId(userId)
if(!formId) {
console.log('没有formId或者formId都已经过期了')
return false
}
console.log('token',token)
let options={
method:'POST',
uri:`https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=${token}`,
body:{
'touser':touserOpenId,// 待推送用户ID
'template_id':template_id,// 模板ID
'page':wx_url,// 小程序页面URL
'form_id':formId,
'data':data
},
json:true// Automatically stringifies the body to JSON
}
// 模板消息推送
request(options)
.then(parsedBody=>{
console.log('推送结果',parsedBody)
// POST succeeded...
})
.catch(function(err) {
console.log(err)
// POST failed...
})
}
//判断token是否过期
function isTokenVaild(token) {
return newPromise(async(resolve,reject)=>{
let isVaild=true
if(token.expires_in>parseInt(newDate().getTime()/1000)) {
// 未过期
console.log('没过期')
console.log('token',token.access_token)
// 判断是否失效
await request({
uri:`https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=${token.access_token}`,
json:true
}).then(function(res) {
if(res.errcode) {
isVaild=false
console.log('失效')
}else{
isVaild=true
}
})
}else{
// 过期
console.log('过期')
isVaild=false
}
resolve(isVaild)
})
}
// 获取并判断token是否失效
async function getToken() {
let token
let isVaild=false
if(global.token) {
isVaild=await isTokenVaild(global.token)
}
return new Promise(async(resolve,reject)=>{
// 判断token是否失效/过期
if(isVaild) {
token=global.token
}else{
// 失效/过期/不存在重新获取
await request({
uri:`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.APP_ID}&secret=${config.APP_SECRET}`,
json:true
}).then((res)=>{
console.log(res)
res.expires_in=parseInt(newDate().getTime()/1000)+res.expires_in// access_token过期时间
console.log('存储token',res)
// 存储token
token={
access_token:res.access_token,
expires_in:res.expires_in
}
global.token=token
})
.catch(function(err) {
console.log(err)
})
}
console.log('最后的access_token',token.access_token)
resolve(token.access_token)
})
}
// 获取有效的formId
function getFormId(userId) {
return new Promise(async(resolve,reject)=>{
let form=await TemplateMsg.findOne({userId:userId})
let formId
if(form.formIdList.length<0) {
resolve(false)
}
let updateFormIdList=JSON.parse(JSON.stringify(form.formIdList))
let isExist=false
form.formIdList.forEach((item,index)=>{
if(item.expire<=parseInt(newDate().getTime())/1000) {
// 过期
console.log('过期',item)
updateFormIdList.splice(index,1)
}else{
// 没过期
isExist=true
formId=item.formId
updateFormIdList.splice(index,1)
return
}
})
console.log('updateFormIdList',updateFormIdList)
// 更新去除过期的formId和将被用掉的formId
let update=await TemplateMsg.updateOne({userId:userId},{$set:{
formIdList:updateFormIdList
}})
if(update.ok===1&&isExist) {
resolve(formId)
}else{
resolve(false)
}
})
}