handleReminders(); }catch (\Exception $exception){ Log::error("发送待办提醒异常", ['msg' => $exception->getMessage()]); } } public function handleReminders() { $now = time(); $wxService = new WxTemplateMessageService(); $appid = config("wx_msg.f_appid"); TodoList::where('status', '<', TodoList::status_two) ->where('del_time', 0) ->where('remind_start', '<=', $now) ->select(TodoList::$field) ->orderBy('id') ->chunkById(10, function ($data) use ($now, $wxService, $appid) { $crtIds = $data->pluck('crt_id')->toArray(); // 查找关联员工 openid $wxInfo = WxEmployeeOfficial::where('employee_id', $crtIds) ->where('type', WxEmployeeOfficial::login_type_two) ->where('appid', $appid) ->pluck('openid','employee_id') ->toArray(); foreach ($data as $todo) { $shouldRemind = false; if ($todo->remind_interval == 0 && empty($todo->last_remind_time)) { $shouldRemind = true; } elseif ($todo->remind_interval > 0 && (empty($todo->last_remind_time) || ($now - $todo->last_remind_time) >= $todo->remind_interval) ) { $shouldRemind = true; } if (! $shouldRemind) continue; // 先发送微信消息(接口可能失败) try { list($status, $msg) = $this->sendReminder($todo, $wxService, $wxInfo); if(! $status) { Log::error("发送待办提醒失败 todo_id: {$todo->id}", ['msg' => $msg]); } } catch (\Throwable $e) { Log::error("发送待办提醒失败 todo_id: {$todo->id}", ['msg' => $e->getMessage()]); } // 再更新数据库(单条事务保护即可) DB::transaction(function () use ($todo, $now) { $todo->last_remind_time = $now; $todo->status = TodoList::status_one; $todo->save(); }); } }); } protected function sendReminder($todo, $wxService, $wxInfo) { // 查找关联员工 openid $openid = $wxInfo[$todo->crt_id] ?? ""; if (! $openid) return [false, '无openid']; // 模板参数 $params = [ 'title' => $todo->title ?? '待办提醒', 'time' => date('Y-m-d H:i:00', $todo->remind_start), ]; // 发送消息 list($status, $msg) = $wxService->sendTemplateMessage('to_do', $params, [ 'openid' => $openid, // 'pagepath' => 'pages/Todo/index/index?id=' . $todo->id, // 小程序路径或URL ]); return [$status, $msg]; } }