feat: 抽离404数据处理 & 支持多时间点提醒

This commit is contained in:
zhaoyingbo 2023-09-21 14:55:01 +08:00
parent bcb9b42db2
commit b4208be2b6
9 changed files with 377 additions and 323 deletions

View File

@ -19,8 +19,8 @@
"litiany4.umijs-plugin-model",
"oderwat.indent-rainbow",
"jock.svg",
"GitHub.copilot",
// "aminer.codegeex",
// "GitHub.copilot",
"aminer.codegeex",
"ChakrounAnas.turbo-console-log",
"Gruntfuggly.todo-tree",
"MS-CEINTL.vscode-language-pack-zh-hans"

View File

@ -23,8 +23,6 @@
[ ] 支持编辑更多设置,飞书网页就行
[ ] 支持同一提醒设置多个时间点
[ ] 支持快速提醒,输入数字,[1-120]分钟
[ ] 销毁创建用卡片,创建卡片添加取消按钮,点击去掉卡片可交互部分
@ -41,6 +39,10 @@
[ ] 离职人员的提醒会发一条通知,然后提醒别人认领
[x] 支持同一提醒设置多个时间
[x] 每个时间支持多时间点设置类似每周一二三每月1 3 10号
[x] 通过info指令在对话里返回请求的数据
[x] 用药提醒的卡片模板,确认、取消、延迟
@ -75,6 +77,10 @@ interface Remind {
* 所有者信息绑定用户表的id
*/
owner: string;
/**
* 消息Id
*/
messageId: string;
/**
* 接收者类型
*/
@ -151,6 +157,31 @@ interface Remind {
*/
delayedTemplateId: string;
} | null;
/**
* 提醒时间
*/
remindTimes: RemindTime[];
/**
* 是否启用
*/
enabled: boolean;
/**
* 下次提醒的时间格式为yyyy-MM-dd HH:mm
*/
nextRemindTime: string;
/**
* 下次提醒时间的中文,类似每天 07:00
*/
nextRemindTimeCHS: string;
}
/**
* 提醒时间
* 为了支持多个时间点提醒,将时间存成数组
*/
interface RemindTime {
/**
* 重复类型
* single: 一次性
@ -170,29 +201,21 @@ interface Remind {
| "workday"
| "holiday";
/**
* 提醒时间格式为HH:mm
* 提醒时间格式为HH:mm single类型时仅作展示用类型为yyyy-MM-dd HH:mm
*/
time: string;
/**
* 星期几当frequency为weekly时有效
* 星期几[1-7]当frequency为weekly时有效
*/
dayOfWeek: number;
daysOfWeek: number[];
/**
* 每月的几号当frequency为monthly时有效
* 每月的几号[1-31]当frequency为monthly时有效
*/
dayOfMonth: number;
daysOfMonth: number[];
/**
* 每年的哪天提醒当frequency为yearly时有效格式为MM-dd
* 每年的哪天提醒当frequency为 yearly 时有效格式为MM-dd
*/
dayOfYear: string;
/**
* 是否启用
*/
enabled: boolean;
/**
* 下次提醒的时间格式为yyyy-MM-dd HH:mm
*/
nextRemindTime: string;
}
```
@ -236,7 +259,7 @@ interface RemindRecord {
/**
* 用户回答的结果
*/
result: string;
result: object;
}
```

View File

@ -1,3 +1,4 @@
const { isSingleRemind } = require("../../utils");
const { genSetRemindCard, genRemindCard } = require("../../utils/genCard");
const { getNextRemindTime } = require("../../utils/nextRemindTime");
const {
@ -5,9 +6,8 @@ const {
upsertRemindByMessageId,
getRemindRecordByMessageId,
getRemind,
updateNextRemindTime,
updateRemind,
updateRemindRecord,
closeRemind,
} = require("../../utils/pb");
const { updateCard } = require("../../utils/sendMsg");
const { trans2LocalTime, getNowStr, getDelayedTimeStr } = require("../../utils/time");
@ -63,10 +63,13 @@ const manageTimePicker = async (body) => {
title: "🍳小煎蛋提醒!",
content: `📝 ${content}`,
},
frequency: "single",
time,
remindTimes: [{
frequency: "single",
time,
}],
enabled: true,
nextRemindTime: time,
nextRemindTimeCHS: time,
};
// 数据库写入提醒这里根据messageId更新或者创建是为了防止垃圾飞书不更新消息
await upsertRemindByMessageId(remindInfo);
@ -99,22 +102,24 @@ const manageBtnClick = async (body) => {
await updateCard(body.open_message_id, card)
// 更新remindRecord
const newRecord = {
...remindRecord,
status: type,
interactTime,
result: JSON.stringify({ type, text, result }),
result: { type, text, result },
}
await updateRemindRecord(remindRecord.id, newRecord)
// 如果是非延迟的单次提醒到此就结束了
if (type !== 'delayed' && remind.frequency === 'single') {
closeRemind(remind.id)
if (type !== 'delayed' && isSingleRemind(remind.remindTimes)) {
updateRemind(remind.id, { enabled: false })
return
}
// 延迟提醒
if (type === 'delayed') {
updateRemind(remind.id, { nextRemindTime: getDelayedTimeStr(remind.delayTime) })
return
}
// 更新下一次的提醒时间
const nextRemindTime = type === 'delayed' ? getDelayedTimeStr(remind.delayTime) : getNextRemindTime(remind)
await updateNextRemindTime(remind.id, nextRemindTime)
updateRemind(remind.id, getNextRemindTime(remind.remindTimes))
};
/**

View File

@ -1,6 +1,7 @@
const { isSingleRemind } = require("../utils")
const { genRemindCard } = require("../utils/genCard")
const { getNextRemindTime } = require("../utils/nextRemindTime")
const { getCurrRemind, updateNextRemindTime, getPendingRemindRecord, updateRemindRecord, createRemindRecord, closeRemind } = require("../utils/pb")
const { getCurrTimeRemind, updateRemind, getPendingRemindRecord, updateRemindRecord, createRemindRecord } = require("../utils/pb")
const { sendMsg, updateCard } = require("../utils/sendMsg")
const { getNowStr, getDelayedTimeStr } = require("../utils/time")
@ -41,14 +42,17 @@ const manageRemind = async (remind) => {
// 创建remindRecord
await createRemindRecord(remind.id, messageId, cardType)
// 如果是不需要回复的单次提醒到此就结束了
if (remind.frequency === 'single' && !remind.needReply) {
closeRemind(remind.id)
if (isSingleRemind(remind.remindTimes) && !remind.needReply) {
updateRemind(remind.id, { enabled: false })
return
}
// 获取下一次提醒时间不需要回复的直接时下一次提醒时间需要回复的则是当前时间延后10min
const nextRemindTime = remind.needReply ? getDelayedTimeStr(remind.delayTime) : getNextRemindTime(remind)
// 更新下一次提醒时间
await updateNextRemindTime(remind.id, nextRemindTime)
// 需要回复的卡片下次提醒时间是delayTimemin之后的时间
if (remind.needReply) {
updateRemind(remind.id, { nextRemindTime: getDelayedTimeStr(remind.delayTime) })
return
}
// 不需要回复的循环提醒,更新下一次的提醒时间
updateRemind(remind.id, getNextRemindTime(remind.remindTimes))
}
/**
@ -56,11 +60,11 @@ const manageRemind = async (remind) => {
* 发送提醒更新上一个pending状态的卡片至delayed
*/
module.exports.sendCurrTimeReminds = async () => {
const remindList = await getCurrRemind()
const remindList = await getCurrTimeRemind()
// 没有需要提醒的卡片
if (!remindList.length) return
if (!remindList?.length) return
// 处理提醒
for (const remind of remindList) {
await manageRemind(remind)
manageRemind(remind)
}
}

114
typings.d.ts vendored
View File

@ -113,6 +113,31 @@ interface Remind {
*/
delayedTemplateId: string;
} | null;
/**
*
*/
remindTimes: RemindTime[];
/**
*
*/
enabled: boolean;
/**
* yyyy-MM-dd HH:mm
*/
nextRemindTime: string;
/**
*
*/
nextRemindTimeCHS: string;
}
/**
*
*
*/
interface RemindTime {
/**
*
* single: 一次性
@ -138,24 +163,17 @@ interface Remind {
/**
* [1-7]frequency为weekly时有效
*/
dayOfWeek: number;
daysOfWeek: number[];
/**
* [1-31]frequency为monthly时有效
*/
dayOfMonth: number;
daysOfMonth: number[];
/**
* frequency为 yearly MM-dd
*/
dayOfYear: string;
/**
*
*/
enabled: boolean;
/**
* yyyy-MM-dd HH:mm
*/
nextRemindTime: string;
}
/**
*
*
@ -190,9 +208,9 @@ interface RemindRecord {
*/
interactTime: string;
/**
*
* 07:00
*/
result: string;
result: object;
}
/**
@ -203,32 +221,32 @@ interface Header {
* ID
* @example 0f8ab23b60993cf8dd15c8cde4d7b0f5
*/
event_id: string;
event_id: string;
/**
* token
* @example tV9djUKSjzVnekV7xTg2Od06NFTcsBnj
*/
token: string;
token: string;
/**
*
* @example 1693565712117
*/
create_time: string;
create_time: string;
/**
*
* @example im.message.receive_v1
*/
event_type: string;
event_type: string;
/**
* tenant_key
* @example 2ee61fe50f4f1657
*/
tenant_key: string;
tenant_key: string;
/**
* app_id
* @example cli_a1eff35b43b89063
*/
app_id: string;
app_id: string;
}
/**
@ -239,17 +257,17 @@ interface UserIdInfo {
*
* @example ou_032f507d08f9a7f28b042fcd086daef5
*/
open_id: string;
open_id: string;
/**
*
* @example on_7111660fddd8302ce47bf1999147c011
*/
union_id: string;
union_id: string;
/**
*
* @example zhaoyingbo
*/
user_id: string;
user_id: string;
}
/**
@ -259,22 +277,22 @@ interface Mention {
/**
* ID信息
*/
id: UserIdInfo;
id: UserIdInfo;
/**
*
* @example "@_user_1"
*/
key: string;
key: string;
/**
*
* @example
*/
name: string;
name: string;
/**
* ID
* @example 2ee61fe50f4f1657
*/
tenant_key: string;
tenant_key: string;
}
/**
@ -285,36 +303,36 @@ interface Message {
* ID
* @example oc_433b1cb7a9dbb7ebe70a4e1a59cb8bb1
*/
chat_id: string;
chat_id: string;
/**
*
* @example group | p2p
*/
chat_type: string;
chat_type: string;
/**
* JSON字符串文本内容
* @example "{\"text\":\"@_user_1 测试\"}"
*/
content: string;
content: string;
/**
*
* @example 1693565711996
*/
create_time: string;
create_time: string;
/**
*
*/
mentions? : Mention[];
mentions?: Mention[];
/**
* ID
* @example om_038fc0eceed6224a1abc1cdaa4266405
*/
message_id: string;
message_id: string;
/**
*
* @example textpostimagefileaudiomediastickerinteractiveshare_chatshare_user
*/
message_type: string;
message_type: string;
}
/**
@ -324,25 +342,25 @@ interface Sender {
/**
* id
*/
sender_id: UserIdInfo;
sender_id: UserIdInfo;
/**
*
* @example user
*/
sender_type: string;
sender_type: string;
/**
* ID
* @example 2ee61fe50f4f1657
*/
tenant_key: string;
tenant_key: string;
}
/**
*
*/
interface Event {
message: Message;
sender: Sender;
message: Message;
sender: Sender;
}
/**
@ -353,15 +371,15 @@ interface LarkMessageEvent {
*
* @example 2.0
*/
schema: string;
schema: string;
/**
*
*/
header: Header;
header: Header;
/**
*
*/
event: Event;
event: Event;
}
/**
@ -371,36 +389,36 @@ interface LarkUserAction {
/**
* open_id
*/
open_id: string;
open_id: string;
/**
*
* @example zhaoyingbo
*/
user_id: string;
user_id: string;
/**
* ID
* @example om_038fc0eceed6224a1abc1cdaa4266405
*/
open_message_id: string;
open_message_id: string;
/**
* ID
* @example oc_433b1cb7a9dbb7ebe70a4e1a59cb8bb1
*/
open_chat_id: string;
open_chat_id: string;
/**
* ID
* @example 2ee61fe50f4f1657
*/
tenant_key: string;
tenant_key: string;
/**
* token
* @example tV9djUKSjzVnekV7xTg2Od06NFTcsBnj
*/
token: string;
token: string;
/**
*
*/
action: {
action: {
/**
*
*/
@ -420,4 +438,4 @@ interface LarkUserAction {
*/
timezone: string;
};
}
}

View File

@ -1,43 +1,3 @@
/**
* 生成提醒时间文本
*/
const genRemindTimeText = (
frequency,
time,
dayOfWeek,
dayOfMonth,
dayOfYear
) => {
const weekCN = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
let remindTimeText = "";
switch (frequency) {
case "single":
remindTimeText = `${dayOfYear} ${time}`;
break;
case "daily":
remindTimeText = `每天 ${time}`;
break;
case "weekly":
remindTimeText = `${weekCN[dayOfWeek - 1]} ${time}`;
break;
case "monthly":
remindTimeText = `每月${dayOfMonth}${time}`;
break;
case "yearly":
remindTimeText = `每年${dayOfYear} ${time}`;
break;
case "workday":
remindTimeText = `工作日 ${time}`;
break;
case "holiday":
remindTimeText = `节假日 ${time}`;
break;
default:
break;
}
return remindTimeText;
};
/**
* 生成交互结果
*/
@ -119,7 +79,7 @@ const genRemindInfo = (
needReply,
cardType,
owner,
remindTime,
nextRemindTimeCHS,
interactTime,
result
) => {
@ -140,7 +100,7 @@ const genRemindInfo = (
});
// 如果是非交互卡片,展示创建人、提醒时间
columns.push(genColumn(`**创建人**\n${owner}`));
columns.push(genColumn(`**提醒时间**\n${remindTime}`));
columns.push(genColumn(`**提醒时间**\n${nextRemindTimeCHS}`));
// 如果是交互卡片,还需要展示交互结果、交互时间
if (needReply) {
columns.push(genColumn(`**交互结果**\n${result}`));
@ -156,10 +116,10 @@ const genRemindInfo = (
/**
* 根据提醒信息生成卡片
* @param {*} remindInfo 提醒信息
* @param {*} cardType 卡片类型
* @param {*} interactInfo 交互信息
* @param {*} interactTime 交互时间在上层已经转成 yyyy-MM-dd HH:mm 格式了
* @param {Remind} remindInfo 提醒信息
* @param {string} cardType 卡片类型
* @param {object} interactInfo 交互信息
* @param {string} interactTime 交互时间在上层已经转成 yyyy-MM-dd HH:mm 格式了
*/
module.exports.genRemindCard = (
remindInfo,
@ -172,22 +132,13 @@ module.exports.genRemindCard = (
cardInfo,
templateInfo,
needReply,
frequency,
time,
dayOfWeek,
dayOfMonth,
dayOfYear,
nextRemindTimeCHS,
expand: {
owner: {
userId: owner,
}
},
} = remindInfo;
// TODO: Onwer信息获取先暂定自己
const owner = "zhaoyingbo";
// 生成提醒时间文本
const remindTime = genRemindTimeText(
frequency,
time,
dayOfWeek,
dayOfMonth,
dayOfYear
);
// 生成交互结果
const result = genResult(interactInfo, cardInfo, cardType);
// 优先返回模板信息
@ -196,11 +147,11 @@ module.exports.genRemindCard = (
cardType === "pending"
? {
owner,
remindTime,
remindTime: nextRemindTimeCHS,
}
: {
owner,
remindTime,
remindTime: nextRemindTimeCHS,
result,
interactTime,
};
@ -261,7 +212,7 @@ module.exports.genRemindCard = (
needReply,
cardType,
owner,
remindTime,
nextRemindTimeCHS,
interactTime,
result
);

11
utils/index.js Normal file
View File

@ -0,0 +1,11 @@
/**
*
* @param {RemindTime[]} remindTimes
*/
const isSingleRemind = (remindTimes) => {
return remindTimes.every(remindTime => remindTime.frequency === 'single')
}
module.exports = {
isSingleRemind,
}

View File

@ -33,14 +33,11 @@ const judgeIsWorkDay = (time) => {
}
/**
* 获取下次提醒时间
* @param {Remind} remind 提醒信息
* @returns {string} 下次提醒时间, 格式为yyyy-MM-dd HH:mm
* 获取指定配置下一次的提醒时间以及对应中文显示
* @param {RemindTime} remindTime 提醒时间配置
*/
module.exports.getNextRemindTime = (remind) => {
const { frequency, time, dayOfWeek, dayOfMonth, dayOfYear } = remind;
// 单次提醒没有下次正常会取delayTime
if (remind.frequency === 'single') return remind.nextRemindTime
const genNextRemindTimeWithCHS = (remindTime) => {
const { frequency, time, daysOfWeek, daysOfMonth, dayOfYear } = remindTime;
// 拆分时间
const [hour, minute] = time.split(':');
// 当前时间
@ -49,34 +46,63 @@ module.exports.getNextRemindTime = (remind) => {
if (frequency === 'daily') {
const remindMoment = moment().hour(hour).minute(minute);
// 判断当前时间是否已经过了今天的提醒时间
if (!remindMoment.isAfter(nowMoment)) {
if (remindMoment.isBefore(nowMoment)) {
// 如果已经过了,那么下次提醒时间为明天的提醒时间
remindMoment.add(1, 'day');
}
return remindMoment.format('YYYY-MM-DD HH:mm');
return {
nextRemindTime: remindMoment.format('YYYY-MM-DD HH:mm'),
nextRemindTimeCHS: `每天 ${time}`,
};
}
// 每周循环
if (frequency === 'weekly') {
const remindMoment = moment().hour(hour).minute(minute).isoWeekday(dayOfWeek);
// 判断当前时间是否已经过了本周的提醒时间
if (!remindMoment.isAfter(nowMoment)) {
// 如果已经过了,那么下次提醒时间为下周的提醒时间
remindMoment.add(1, 'week');
}
return remindMoment.format('YYYY-MM-DD HH:mm');
// 也是取离当前时间点最近的某一天
return daysOfWeek.reduce(({ nextRemindTime, nextRemindTimeCHS }, dayOfWeek) => {
const remindMoment = moment().hour(hour).minute(minute).isoWeekday(dayOfWeek);
// 判断当前时间是否已经过了本周的提醒时间
if (remindMoment.isBefore(nowMoment)) {
// 如果已经过了,那么下次提醒时间为下周的提醒时间
remindMoment.add(1, 'week');
}
// 取最近的时间
if (remindMoment.isBefore(moment(nextRemindTime))) {
return {
nextRemindTime: remindMoment.format('YYYY-MM-DD HH:mm'),
nextRemindTimeCHS: `${["周一", "周二", "周三", "周四", "周五", "周六", "周日"][dayOfWeek - 1]} ${time}`
}
}
return {
nextRemindTime,
nextRemindTimeCHS,
}
}, { nextRemindTime: '2099-12-31 23:59', nextRemindTimeCHS: '' })
}
// 每月循环
if (frequency === 'monthly') {
// 获取最近应该提醒的日期如果一个月没有31天那么就是最后一天
const dayOfMonthNum = moment().daysInMonth();
const remindMoment = moment().hour(hour).minute(minute).date(dayOfMonthNum < dayOfMonth ? dayOfMonthNum : dayOfMonth);
// 判断当前时间是否已经过了本月的提醒时间
if (!remindMoment.isAfter(nowMoment)) {
// 如果已经过了那么下次提醒时间为下月的提醒时间需要重新判断一下是否有31号
const nextDayOfMonthNum = moment().add(1, 'month').daysInMonth();
remindMoment.add(1, 'month').date(nextDayOfMonthNum < dayOfMonth ? nextDayOfMonthNum : dayOfMonth);
}
return remindMoment.format('YYYY-MM-DD HH:mm');
// 也是取里当前时间点最近的某一天
return daysOfMonth.reduce(({ nextRemindTime, nextRemindTimeCHS }, dayOfMonth) => {
// 获取最近应该提醒的日期如果一个月没有31天那么就是最后一天
const dayOfMonthNum = moment().daysInMonth();
const remindMoment = moment().hour(hour).minute(minute).date(dayOfMonthNum < dayOfMonth ? dayOfMonthNum : dayOfMonth);
// 判断当前时间是否已经过了本月的提醒时间
if (remindMoment.isBefore(nowMoment)) {
// 如果已经过了那么下次提醒时间为下月的提醒时间需要重新判断一下是否有31号
const nextDayOfMonthNum = moment().add(1, 'month').daysInMonth();
remindMoment.add(1, 'month').date(nextDayOfMonthNum < dayOfMonth ? nextDayOfMonthNum : dayOfMonth);
}
// 取最近的时间
if (remindMoment.isBefore(moment(nextRemindTime))) {
return {
nextRemindTime: remindMoment.format('YYYY-MM-DD HH:mm'),
nextRemindTimeCHS: `每月${dayOfMonth}${time}`
}
}
return {
nextRemindTime,
nextRemindTimeCHS,
}
}, { nextRemindTime: '2099-12-31 23:59', nextRemindTimeCHS: '' })
}
// 每年循环
if (frequency === 'yearly') {
@ -88,12 +114,15 @@ module.exports.getNextRemindTime = (remind) => {
const dayOfMonthNum = moment().month(month).daysInMonth();
const remindMoment = moment().hour(hour).minute(minute).month(month).date(dayOfMonthNum < dayOfMonth ? dayOfMonthNum : dayOfMonth);
// 判断当前时间是否已经过了今年的提醒时间
if (!remindMoment.isAfter(nowMoment)) {
if (remindMoment.isBefore(nowMoment)) {
// 如果已经过了那么下次提醒时间为明年的提醒时间需要重新判断一下是否有29号
const nextDayOfMonthNum = moment().add(1, 'year').month(month).daysInMonth();
remindMoment.add(1, 'year').date(nextDayOfMonthNum < dayOfMonth ? nextDayOfMonthNum : dayOfMonth);
}
return remindMoment.format('YYYY-MM-DD HH:mm');
return {
nextRemindTime: remindMoment.format('YYYY-MM-DD HH:mm'),
nextRemindTimeCHS: `每年${dayOfYear} ${time}`
};
}
// 工作日循环
if (frequency === 'workday') {
@ -101,13 +130,16 @@ module.exports.getNextRemindTime = (remind) => {
// 今天是否是工作日
const isWorkday = judgeIsWorkDay();
// 如果今天非工作日或者如果是工作日,且当前时间过了提醒时间,那么下次提醒时间为下次工作日的提醒时间
if (!isWorkday || (isWorkday && !remindMoment.isAfter(nowMoment))) {
if (!isWorkday || (isWorkday && remindMoment.isBefore(nowMoment))) {
remindMoment.add(1, 'day');
while (!judgeIsWorkDay(remindMoment)) {
remindMoment.add(1, 'day');
}
}
return remindMoment.format('YYYY-MM-DD HH:mm');
return {
nextRemindTime: remindMoment.format('YYYY-MM-DD HH:mm'),
nextRemindTimeCHS: `工作日 ${time}`
};
}
// 非工作日循环
if (frequency === 'holiday') {
@ -115,12 +147,42 @@ module.exports.getNextRemindTime = (remind) => {
// 今天是否是工作日
const isWorkday = judgeIsWorkDay();
// 如果今天是工作日或者如果是非工作日,且当前时间过了提醒时间,那么下次提醒时间为下次非工作日的提醒时间
if (isWorkday || (!isWorkday && !remindMoment.isAfter(nowMoment))) {
if (isWorkday || (!isWorkday && remindMoment.isBefore(nowMoment))) {
remindMoment.add(1, 'day');
while (judgeIsWorkDay(remindMoment)) {
remindMoment.add(1, 'day');
}
}
return remindMoment.format('YYYY-MM-DD HH:mm');
return {
nextRemindTime: remindMoment.format('YYYY-MM-DD HH:mm'),
nextRemindTimeCHS: `节假日 ${time}`
};
}
}
// 单次提醒
// 此时的time是完整的时间直接返回即可
return {
nextRemindTime: time,
nextRemindTimeCHS: time,
}
}
/**
* 获取下次提醒时间在传入的所有时间配置中获取最早的一个
* @param {RemindTime[]} remindTimes 提醒信息
* @returns {{ nextRemindTime: string, nextRemindTimeCHS: string }} 下次提醒时间, 格式为yyyy-MM-dd HH:mm 以及对应中文显示
*/
module.exports.getNextRemindTime = (remindTimes) => {
return remindTimes.reduce(({ nextRemindTime, nextRemindTimeCHS }, remindTime) => {
const { nextRemindTime: nextTime, nextRemindTimeCHS: nextTimeCHS } = genNextRemindTimeWithCHS(remindTime)
if (moment(nextTime).isBefore(moment(nextRemindTime))) {
return {
nextRemindTime: nextTime,
nextRemindTimeCHS: nextTimeCHS,
}
}
return {
nextRemindTime,
nextRemindTimeCHS,
}
}, { nextRemindTime: '2099-12-31 23:59', nextRemindTimeCHS: '' });
}

View File

@ -4,38 +4,11 @@ require('cross-fetch/polyfill')
const pb = new PocketBase('https://eggpb.imoaix.cn')
/**
* 更新租户的token
* @param {string} value 新的token
*/
module.exports.updateTenantAccessToken = async (value) => {
await pb.collection('config').update('ugel8f0cpk0rut6', { value })
console.log('reset access token success', value)
}
/**
* 获取租户的token
* @returns {string} 租户的token
*/
module.exports.getTenantAccessToken = async () => {
const { value } = await pb.collection('config').getOne('ugel8f0cpk0rut6')
return value
}
/**
* 创建新提醒
*/
module.exports.createRemind = async (remind) => {
await pb.collection('remind').create(remind)
}
/**
* 获取提醒信息
*/
module.exports.getRemind = async (id) => {
const manage404 = async (dbFunc) => {
try {
return await pb.collection('remind').getOne(id)
return await dbFunc()
} catch (err) {
console.log('errdfsfsfsfsdf', err)
// 没有这个提醒就返回空
if (err.message === "The requested resource wasn't found.") {
return null
@ -44,120 +17,118 @@ module.exports.getRemind = async (id) => {
}
/**
* 根据messageId更新或者创建提醒
* @param {Remind} remind
* 更新租户的token
* @param {string} value 新的token
*/
module.exports.upsertRemindByMessageId = async (remind) => {
try {
const record = await pb.collection('remind').getFirstListItem(
`messageId = "${remind.messageId}" && enabled = true`
)
await pb.collection('remind').update(record.id, remind)
} catch (err) {
// 没有这个提醒就创建
if (err.message === "The requested resource wasn't found.") {
await pb.collection('remind').create(remind)
} else throw err;
}
const updateTenantAccessToken = async (value) => {
await pb.collection('config').update('ugel8f0cpk0rut6', { value })
console.log('reset access token success', value)
}
/**
* 获取租户的token
* @returns {string} 租户的token
*/
const getTenantAccessToken = async () => {
const { value } = await pb.collection('config').getOne('ugel8f0cpk0rut6')
return value
}
/**
* 创建新提醒
* @param {Remind} remind 提醒内容
*/
const createRemind = async (remind) => {
return await pb.collection('remind').create(remind)
}
/**
* 更新提醒
* @param {string} remindId 提醒ID
* @param {Remind} remind 提醒内容
*/
const updateRemind = async (remindId, remind) => {
return await pb.collection('remind').update(remindId, remind)
}
/**
* 获取提醒信息
* @param {string} id 提醒ID
* @returns {Remind | null}
*/
const getRemind = async (remindId) => manage404(async () =>
await pb.collection('remind').getOne(remindId, { expand: 'owner' })
)
/**
* 获取对应messageId对应的提醒
* @param {string} messageId 消息ID
* @returns {Remind | null}
*/
const getRemindByMessageId = async (messageId) => manage404(async () =>
await pb.collection('remind').getFirstListItem(
`messageId = "${messageId}" && enabled = true`
)
)
/**
* 根据messageId更新或者创建提醒
* @param {Remind} remind 提醒内容
*/
const upsertRemindByMessageId = async (remind) => {
const record = await getRemindByMessageId(remind.messageId)
if (record) updateRemind(record.id, remind)
else createRemind(remind)
}
/**
* 获取当前分钟应该提醒的所有提醒
*/
module.exports.getCurrRemind = async () => {
const nowStr = getNowStr()
// TODO: 应该不会同时出现同一时间100个需要提醒的情况等通知系统完善这里加个分页提醒吧
const { items } = await pb.collection('remind').getList(1, 100, {
filter: `nextRemindTime = "${nowStr}" && enabled = true`,
const getCurrTimeRemind = async () => manage404(async () => {
const { items } = await pb.collection('remind').getList(1, 1000, {
filter: `nextRemindTime = "${getNowStr()}" && enabled = true`,
expand: 'owner'
})
return items
}
/**
* 获取对应messageId对应的提醒
*/
module.exports.getRemindByMessageId = async (messageId) => {
try {
const record = await pb.collection('remind').getFirstListItem(
`messageId = "${messageId}" && enabled = true`
)
return record
} catch (err) {
// 没有这个提醒不返回
if (err.message === "The requested resource wasn't found.") {
return null
} else throw err;
}
}
/**
* 更新指定Remind的下次提醒时间
* @param {string} remindId 提醒信息Id
* @param {string} nextRemindTime 下次提醒时间
*/
module.exports.updateNextRemindTime = async (remindId, nextRemindTime) => {
await pb.collection('remind').update(remindId, { nextRemindTime })
}
/**
* 关闭指定的Remind
* @param {string} remindId 提醒信息Id
*/
module.exports.closeRemind = async (remindId) => {
await pb.collection('remind').update(remindId, { enabled: false })
}
})
/**
* 获取指定remind的pending状态的remindRecord
* @param {string} remindId remind的id
* @returns {RemindRecord | null} remindRecord
*/
module.exports.getPendingRemindRecord = async (remindId) => {
try {
const record = await pb.collection('remindRecord').getFirstListItem(
`remindId = "${remindId}" && status = "pending"`
)
return record
} catch (err) {
// 没有这个record不返回
if (err.message === "The requested resource wasn't found.") {
return null
} else throw err;
}
}
const getPendingRemindRecord = async (remindId) => manage404(async () =>
await pb.collection('remindRecord').getFirstListItem(
`remindId = "${remindId}" && status = "pending"`
)
)
/**
* 获取指定messageId状态的remindRecord
* @param {string} remindId remind的id
* @returns {RemindRecord | null} remindRecord
*/
module.exports.getRemindRecordByMessageId = async (messageId) => {
try {
const record = await pb.collection('remindRecord').getFirstListItem(
`messageId = "${messageId}"`
)
return record
} catch (err) {
// 没有这个record不返回
if (err.message === "The requested resource wasn't found.") {
return null
} else throw err;
}
}
const getRemindRecordByMessageId = async (messageId) => manage404(async () =>
await pb.collection('remindRecord').getFirstListItem(
`messageId = "${messageId}"`
)
)
/**
* 创建remindRecord
* @param {string} remindId 提醒ID
* @param {string} messageId 消息ID
* @param {string} status 交互状态
*/
module.exports.createRemindRecord = async (remindId, messageId, status) => {
const createRemindRecord = async (remindId, messageId, status) => {
const remindRecord = {
remindId,
messageId,
status: status,
remindTime: getNowStr(),
interactTime: status === 'pending' ? '' : getNowStr(),
result: '',
}
await pb.collection('remindRecord').create(remindRecord)
return await pb.collection('remindRecord').create(remindRecord)
}
/**
@ -165,8 +136,8 @@ module.exports.createRemindRecord = async (remindId, messageId, status) => {
* @param {string} id remindRecord的id
* @param {RemindRecord} record remindRecord的信息
*/
module.exports.updateRemindRecord = async (id, record) => {
await pb.collection('remindRecord').update(id, record)
const updateRemindRecord = async (id, record) => {
return await pb.collection('remindRecord').update(id, record)
}
/**
@ -174,9 +145,9 @@ module.exports.updateRemindRecord = async (id, record) => {
* @param {string} userId 用户id
* @returns {User} 用户信息
*/
const getUser = async (userId) => {
return await pb.collection("user").getFirstListItem(`userId="${userId}"`)
}
const getUser = async (userId) => manage404(async () =>
await pb.collection("user").getFirstListItem(`userId="${userId}"`)
)
/**
* 创建用户
@ -191,7 +162,7 @@ const createUser = async (userId, openId) => {
/**
* 更新用户信息
* @param {string} id 用户id
* @param {*} data 用户信息
* @param {User} data 用户信息
* @returns {User} 用户信息
*/
const updateUser = async (id, data) => {
@ -200,25 +171,34 @@ const updateUser = async (id, data) => {
/**
* 更新用户信息如果用户不存在则创建
* @param {User} userInfo
* @param {User} userInfo 用户信息
* @returns {User} 用户信息
*/
module.exports.upsertUser = async (userInfo) => {
try {
const user = await getUser(userInfo.user_id);
// 如果用户信息没变化,直接返回
if (user.openId === userInfo.open_id) {
return user;
}
// 如果用户信息有变化,更新
return await updateUser(user.id, {
openId: userInfo.open_id,
});
} catch (err) {
// 没有这个用户上传个新的
if (err.message === "The requested resource wasn't found.") {
const user = await createUser(userInfo.user_id, userInfo.open_id);
return user;
} else throw err;
const upsertUser = async (userInfo) => {
const user = await getUser(userInfo.user_id);
if (!user) return await createUser(userInfo.user_id, userInfo.open_id);
// 如果用户信息没变化,直接返回
if (user.openId === userInfo.open_id) {
return user;
}
}
// 如果用户信息有变化,更新
return await updateUser(user.id, {
openId: userInfo.open_id,
});
}
module.exports = {
updateTenantAccessToken,
getTenantAccessToken,
createRemind,
updateRemind,
getRemind,
getRemindByMessageId,
upsertRemindByMessageId,
getCurrTimeRemind,
getPendingRemindRecord,
getRemindRecordByMessageId,
createRemindRecord,
updateRemindRecord,
upsertUser,
}