feat(todo): 聊天待办支持提醒时间(到点引用原消息+@提及)
给消息待办增加可选「提醒时间」,到点由 todo-alert 机器人对原消息发起 reply、正文 @ 仍在群内的被指派成员,完全复用原生回复/提及链路(定向未读、 红点、绕过会话免打扰、App 推送);被指派人全部退群则跳过发送并标记已提醒。 设/改/取消提醒的权限沿用 todo_set_permission 开关与 checkTodoOwnerPermission。 后端: - 迁移:web_socket_dialog_msg_todos 增加 remind_at/reminded_at 及索引, 注册为日期字段 - WebSocketDialogMsgTodo::dueReminders() 选取到点(未提醒/未完成)待办(limit 500) - WebSocketDialogMsg::setTodoRemind() 纯数据写入(改时间重置 reminded_at), 接入 toggleTodoMsg($remindAt) 与 msg__todo 透传 - 接口 msg__todoremind 设置/修改/取消提醒(权限闸门、消息类型校验、 pushMsg 同步 todo_done) - TodoRemindTask 到点按消息发提醒(reminded_at 防重复、迟发补发、原消息/ 会话删除兜底),buildRemindText 生成 <span class="mention user"> 文本, 接入 crontab;登记 todo-alert 机器人 - msgJoinGroup 从提醒文本中提取被 @ 成员 前端: - 设待办弹窗新增「提醒时间」(预设 + 自定义 DatePicker) - 待办详情浮层每条待办可查看/修改/取消提醒:DatePicker on-clear「清空」 二次确认后取消,无时间时仅关闭面板不发请求 - 待办浮层窄屏(≤500px)改为 待办/完成 tab 切换,宽屏维持双列;列表为空 展示空状态占位;提醒时间用 Icon 替换 emoji - 时间读写对齐项目任务时间的时区约定 测试:tests/Feature/TodoRemindTest(数据/选取/写入/权限决策/buildRemindText/ text mention 提取),TodoSetPermissionTest 无回归。 任务 #124 后续增强。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -414,7 +414,7 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
* @param array $userids 设置给指定会员
|
||||
* @return mixed
|
||||
*/
|
||||
public function toggleTodoMsg($sender, $userids = [])
|
||||
public function toggleTodoMsg($sender, $userids = [], $remindAt = false)
|
||||
{
|
||||
if (in_array($this->type, ['tag', 'todo', 'notice'])) {
|
||||
return Base::retError('此消息不支持设待办');
|
||||
@@ -485,12 +485,39 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
];
|
||||
$dialog->pushMsg('update', $upData);
|
||||
//
|
||||
// 提醒时间:仅当调用方显式传入时处理(false=不传则不动既有提醒)
|
||||
if ($remindAt !== false) {
|
||||
$this->setTodoRemind($userids, $remindAt ?: null);
|
||||
}
|
||||
//
|
||||
return Base::retSuccess($this->todo ? '设置成功' : '取消成功', [
|
||||
'add' => $addData,
|
||||
'update' => $upData,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置/取消本消息指定成员待办的提醒时间(纯数据,无推送)。
|
||||
* 改动会把 reminded_at 重置为 null,使其可再次到点提醒。
|
||||
*
|
||||
* @param array $userids 目标成员
|
||||
* @param string|null $remindAt 提醒时间字符串;null/空 表示取消提醒
|
||||
* @return int 受影响行数
|
||||
*/
|
||||
public function setTodoRemind(array $userids, $remindAt = null)
|
||||
{
|
||||
$userids = array_values(array_filter(array_map('intval', $userids)));
|
||||
if (empty($userids)) {
|
||||
return 0;
|
||||
}
|
||||
return WebSocketDialogMsgTodo::whereMsgId($this->id)
|
||||
->whereIn('userid', $userids)
|
||||
->update([
|
||||
'remind_at' => $remindAt ?: null,
|
||||
'reminded_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转发消息
|
||||
* @param array|int $dialogids
|
||||
|
||||
Reference in New Issue
Block a user