|
|
@@ -0,0 +1,125 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Jobs;
|
|
|
+
|
|
|
+use App\Model\TodoList;
|
|
|
+use App\Model\WxEmployeeOfficial;
|
|
|
+use App\Service\Weixin\WxTemplateMessageService;
|
|
|
+use Illuminate\Bus\Queueable;
|
|
|
+use Illuminate\Contracts\Queue\ShouldQueue;
|
|
|
+use Illuminate\Foundation\Bus\Dispatchable;
|
|
|
+use Illuminate\Queue\InteractsWithQueue;
|
|
|
+use Illuminate\Queue\SerializesModels;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+use Illuminate\Support\Facades\Redis;
|
|
|
+use MongoDB\Driver\Exception\Exception;
|
|
|
+use Symfony\Component\Console\Output\ConsoleOutput;
|
|
|
+use Symfony\Component\Console\Output\OutputInterface;
|
|
|
+
|
|
|
+class TodoRemindJob implements ShouldQueue
|
|
|
+{
|
|
|
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
+
|
|
|
+ public $todoId;
|
|
|
+ public $tries = 1;
|
|
|
+
|
|
|
+ public function __construct($todoId)
|
|
|
+ {
|
|
|
+ $this->todoId = $todoId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function handle()
|
|
|
+ {
|
|
|
+ $this->doJob();
|
|
|
+ }
|
|
|
+
|
|
|
+ private function doJob(){
|
|
|
+ $now = time();
|
|
|
+ $appid = config("wx_msg.f_appid");
|
|
|
+ $wxSrv = new WxTemplateMessageService();
|
|
|
+
|
|
|
+ $todo = TodoList::find($this->todoId);
|
|
|
+ if (!$todo || $todo->del_time != 0 || $todo->status >= TodoList::status_two) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分布式锁
|
|
|
+ $lockKey = "todo_remind_lock:" . $todo->id;
|
|
|
+ $lock = Cache::lock($lockKey, 5);
|
|
|
+
|
|
|
+ if (! $lock->get()) {
|
|
|
+ return; // 其他进程在处理,直接跳过
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // ======================
|
|
|
+ // 1. 是否应该提醒
|
|
|
+ // ======================
|
|
|
+ if (! $this->shouldRemind($todo, $now)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查 openid
|
|
|
+ $openid = WxEmployeeOfficial::where('employee_id', $todo->crt_id)
|
|
|
+ ->where('type', WxEmployeeOfficial::login_type_two)
|
|
|
+ ->where('appid', $appid)
|
|
|
+ ->value('openid');
|
|
|
+
|
|
|
+ if (!$openid) {
|
|
|
+ $this->updateTodoStatus($todo, $now, '无openid');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ======================
|
|
|
+ // 2. 调微信接口发送
|
|
|
+ // ======================
|
|
|
+ list($ok, $msg) = $wxSrv->sendTemplateMessage('to_do', [
|
|
|
+ 'title' => $todo->title ?? '待办提醒',
|
|
|
+ 'time' => date('Y-m-d H:i:00', $todo->remind_start),
|
|
|
+ ], [
|
|
|
+ 'openid' => $openid,
|
|
|
+ 'pagepath' => 'pages/todoManage/add?type=4&id=' . $todo->id,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $this->updateTodoStatus($todo, $now, $msg);
|
|
|
+
|
|
|
+ } finally {
|
|
|
+ $lock->release();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function shouldRemind($todo, $now)
|
|
|
+ {
|
|
|
+ if ($todo->remind_interval == 0 && empty($todo->last_remind_time)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($todo->remind_interval > 0) {
|
|
|
+ if (empty($todo->last_remind_time)) return true;
|
|
|
+ return ($now - $todo->last_remind_time) >= $todo->remind_interval;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function updateTodoStatus($todo, $now, $msg)
|
|
|
+ {
|
|
|
+ $msg = is_scalar($msg) ? $msg : json_encode($msg, JSON_UNESCAPED_UNICODE);
|
|
|
+
|
|
|
+ TodoList::where('id', $todo->id)
|
|
|
+ ->where('last_remind_time', $todo->last_remind_time ?? 0)
|
|
|
+ ->update([
|
|
|
+ 'last_remind_time' => $now,
|
|
|
+ 'status' => TodoList::status_one,
|
|
|
+ 'last_time_result' => $msg,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function echoMessage(OutputInterface $output)
|
|
|
+ {
|
|
|
+ //输出消息
|
|
|
+ $output->writeln(json_encode($this->data));
|
|
|
+ }
|
|
|
+}
|