v3.6.0 日期:2020/06/05
- 修改了法语背单词部分功能
- 修改了词书和背词数量后,立即生效
- 增加了学习提醒
- 增加了简易的帮助说明
- 修改了其他细节
小程序主页:法语记忆 学背单词动词变位
法语背单词
看不见的调整
标准单词本
:每个单词本一条词库,这里的单词没有任何其他附加信息,也就是说都是等级为 0 的新词,是生成的或者直接拷贝在数据库中。有印象的单词
:用户词库。用户词库是一个对象数组,每个对象内有:单词信息、日期信息(UNIX 时间戳)、单词等级信息(等级至少为 1)。
首先是生成当天需要的几个数组:今日新词
、今天要学习
、今天要复习
、有印象的单词
(已有):
- 每天第一次打开小程序的时候,根据用户选择的词书生成
标准单词本
。 标准单词本
和有印象的单词
进行对比,去除用户选择的标准单词本
中有印象的单词
已有的单词,然后生成当天可能的词汇背诵列表
。- 再根据用户安排的
背词量
从可能的词汇背诵列表
中提取今日新词
。 - 筛选
有印象的单词
中日期信息为当天的单词和今日新词
组成为今天要学习
的单词。
有了上面这些步骤之后:
标准单词本
永远不会变,除非词库作者更改。- 用户见到了一个新词或者对旧词做过相应的判断(点击了
认识
或者不认识
)
有印象的单词
会变(新增单词、等级上升、下降、日期信息改变)。今天要学习
会变(去除有印象的单词
产生变化的单词)。
- 始终保存
有印象的单词
,而今天要学习
根据用户设置和新的一天时间而改变。
修改背单词设置立即生效
同样是看不见的修改:由于做了上面的调整,那么背单词的词书设置
和每日新词数量
在修改完毕之后,即可在背单词主页看到更改效果,不必等到第二天 0 点。
此外,进行了这些“看不见”的修改后,还有同步设置和一些与旧版本兼容性问题是必须要做的。(尽量都考虑到了,不然就会出现没法背单词的情况 😂)
看得见的调整
- 调整了
认单词
页面的按钮,两个就行了,当中那个我觉得没什么用且增加用户选择成本 😂。 - 增加了简易的使用说明。
小程序能力:订阅消息
- 首先要在小程序管理后台中开通
订阅消息
功能,并新增一个消息模板,记录下模板 ID。 - 使用
wx.requestSubscribeMessage
会拉起用户授权“发送一次以下消息”的提示框,当用户允许后执行接下来的内容。
- 使用
db.collection
去检查数据库中寻找是否设置过且没有发送过的消息。 - 如果没有,则使用
wx.cloud.callFunction
调用名叫subscribe
的小程序云函数
如果有个按钮…
如果有个按钮绑定了函数subscribeMessege
,用来实现订阅消息
。
subscribeMessege: function (e) {
//使用`wx.requestSubscribeMessage`会拉起用户授权“发送一次以下消息”的提示框,当用户允许后执行接下来的内容。
wx.requestSubscribeMessage({
tmplIds: ['模板ID string'],
success(res) {
if (res.errMsg == "requestSubscribeMessage:ok") {
const db = wx.cloud.database()
//使用`db.collection`去检查数据库中寻找是否设置过且没有发送过的消息。
db.collection('数据库中集合的名称').where({
touser: app.globalData.openid,
done: false
}).get({
success: function (res) {
if (res.data.length != 0) {
wx.showToast({
title: '您已设置过',
icon: 'none',
duration: 1500
})
}
//如果没有,则使用`wx.cloud.callFunction`调用名叫`subscribe`的`小程序云函数`
if (res.data.length == 0) {
wx.cloud.callFunction({
touser: app.globalData.openid,
name: "subscribe",
data: {},
success: function (res) {
wx.showToast({
title: '设置成功',
icon: 'success',
duration: 1500
})
},
fail: console.error
})
}
}
});
} else {
wx.showToast({
title: '设置失败',
icon: 'none',
duration: 1500
})
}
}
})
},
创建两个云函数
- 在文件夹
cloud-functions
中新建两个云函数subscribe
和send
。(具体可以查看小程序官方文档) subscribe
负责生成订阅消息并将它放入数据库。send
负责发送订阅消息。
subscribe
云函数:
// 云函数入口文件
const cloud = require("wx-server-sdk");
cloud.init();
const db = cloud.database();
// 云函数入口函数
exports.main = async (event, context) => {
try {
const { OPENID } = cloud.getWXContext();
// 生成UNIX时间戳,将要提醒的时间
var repeat_date = Date.parse(new Date()) + 86400000; //毫秒
//将消息和它的发送时间存入数据库
const result = await db.collection("数据库中集合的名称").add({
data: {
touser: OPENID,
page: "pages/welcome/welcome",
data: {
thing1: {
value: "是时候背单词、动词变位啦!",
},
thing2: {
value: "点击这里立即开始学习。",
},
thing4: {
value: "本消息仅出现一次,再次提醒需要重新设置。",
},
},
templateId: "模板ID",
repeat_date: repeat_date,
done: false,
},
});
console.log(result);
return result;
} catch (err) {
console.log(err);
return err;
}
};
send
云函数:
- 数据库里面的日期时间戳小于当时的时间戳且未被发送的消息 → 将会被发送。
cloud.openapi.subscribeMessage.send
发送消息。- 更新数据库中消息的发送状态为
true
(已发送)。
// 云函数入口文件
const cloud = require("wx-server-sdk");
// 云函数入口函数
exports.main = async (event, context) => {
cloud.init();
const db = cloud.database();
// 生成UNIX时间戳,将要提醒的时间
var today_date = Date.parse(new Date());
try {
const _ = db.command;
const messages = await db
.collection("subscribeMessages")
.where({
// 数据库里面的日期时间戳小于当时的时间戳且未被发送的消息→将会被发送
repeat_date: _.lt(today_date),
done: false,
})
.get();
const sendPromises = messages.data.map(async (message) => {
try {
await cloud.openapi.subscribeMessage.send({
touser: message.touser,
page: message.page,
data: message.data,
templateId: message.templateId,
});
return db
.collection("数据库中集合的名称")
.doc(message._id)
.update({
data: {
done: true,
},
});
} catch (e) {
return e;
}
});
return Promise.all(sendPromises);
} catch (err) {
return err;
}
};
定时发送:定时触发器
- 设置定时器,定时执行
send
云函数,比如定时 10 分钟。也就是说每隔 10 分钟执行send
云函数一次来检查数据库里面还有哪些未被发送的订阅消息。 - 在
send
函数中的config.json
文件中加入触发器
。(关于触发器可以查看官方文档)
{
"permissions": {
"openapi": ["subscribeMessage.send"]
},
"triggers": [
{
"name": "myTrigger",
"type": "timer",
"config": "20 */10 * * * * *"
}
]
}
参考资料
关于订阅消息主要有用的参考资料除了官方文档外,就只有以下一篇文章: