Skip to content

Commit

Permalink
perf: 优化任务到期前后邮件提醒
Browse files Browse the repository at this point in the history
  • Loading branch information
kuaifan committed Apr 7, 2022
1 parent 9bc56f5 commit 601d037
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 92 deletions.
51 changes: 0 additions & 51 deletions app/Models/ProjectTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -1264,55 +1264,4 @@ public static function userTask($task_id, $archived = true, $trashed = true, $pe
//
return $task;
}

/**
* 预超期任务提醒
* @param $task
*/
public static function overdueRemindEmail($task)
{
$ownerIds = ProjectTaskUser::whereTaskId($task['id'])->whereOwner(1)->pluck('userid')->toArray();
$users = User::whereIn('userid', $ownerIds)->get();
if (!$users) {
throw new ApiException("ProjectTask::overdueRemindEmail--没有负责人");
}
$type = $task['end_at'] < Carbon::now() ? 2 : 1;
$setting = Base::setting('emailSetting');
$hours = floatval($setting['task_remind_hours']);
$hours2 = floatval($setting['task_remind_hours2']);
$time = $type === 1 ? $hours : $hours2;
UserEmailVerification::initMailConfig();
foreach ($users as $user) {
/** @var User $user */
if (ProjectTaskMailLog::whereTaskId($task['id'])->whereUserid($user->userid)->whereType($type)->whereIsSend(1)->exists()) {
return;
}
$email = $user->email;
$isSend = 1;
try {
$emailContent = [
'name' => $task['name'],
'time' => $time,
'type' => $type
];
Mail::send('taskOverdueRemind', $emailContent, function ($m) use ($email) {
$m->from(Config::get("mail.mailers.smtp.username"), env('APP_NAME'));
$m->to($email);
$m->subject("任务提醒");
});
} catch (\Exception $e) {
$isSend = 0;
\Log::error($email . '--邮箱发送报错:', [$e->getMessage()]);
}
$logData = [
'userid' => $user->userid,
'task_id' => $task['id'],
'email' => $email,
'type' => $type,
'is_send' => $isSend,
];
$emailLog = ProjectTaskMailLog::whereTaskId($task['id'])->whereUserid($user->userid)->whereType($type)->first();
ProjectTaskMailLog::createInstance($logData, $emailLog->id ?? null)->save();
}
}
}
2 changes: 2 additions & 0 deletions app/Models/ProjectTaskMailLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* @property string|null $email 电子邮箱
* @property int|null $type 提醒类型:1第一次任务提醒,2第二次任务超期提醒
* @property int|null $is_send 邮件发送是否成功:0否,1是
* @property string|null $send_error 邮件发送错误详情
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
Expand All @@ -28,6 +29,7 @@
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereIsSend($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereSendError($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereTaskId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereUpdatedAt($value)
Expand Down
104 changes: 82 additions & 22 deletions app/Tasks/OverdueRemindEmailTask.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php


namespace App\Tasks;

use App\Models\ProjectTask;
use App\Models\ProjectTaskMailLog;
use App\Models\User;
use App\Module\Base;
use Carbon\Carbon;
use Guanguans\Notify\Factory;
use Guanguans\Notify\Messages\EmailMessage;

@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);

Expand All @@ -22,35 +25,92 @@ public function start()
if ($setting['notice'] === 'open') {
$hours = floatval($setting['task_remind_hours']);
$hours2 = floatval($setting['task_remind_hours2']);
$taskLists1 = [];
$taskLists2 = [];
if ($hours > 0) {
$taskLists1 = ProjectTask::whereNull('complete_at')
->where('end_at', '>=', Carbon::now()->addMinutes($hours * 60 - 3)->rawFormat('Y-m-d H:i:s'))
->where('end_at', '<=', Carbon::now()->addMinutes($hours * 60 + 3)->rawFormat('Y-m-d H:i:s'))
ProjectTask::whereNull('complete_at')
->whereNull('archived_at')
->take(100)
->get()
->toArray();
->whereBetween("end_at", [
Carbon::now()->addMinutes($hours * 60 - 3),
Carbon::now()->addMinutes($hours * 60 + 3)
])->chunkById(100, function ($tasks) {
/** @var ProjectTask $task */
foreach ($tasks as $task) {
$this->overdueBeforeAfterEmail($task, true);
}
});
}
if ($hours2 > 0) {
$taskLists2 = ProjectTask::whereNull('complete_at')
->where('end_at', '>=', Carbon::now()->subMinutes($hours2 * 60 + 3)->rawFormat('Y-m-d H:i:s'))
->where('end_at', '<=', Carbon::now()->subMinutes($hours2 * 60 - 3)->rawFormat('Y-m-d H:i:s'))
ProjectTask::whereNull('complete_at')
->whereNull('archived_at')
->take(100)
->get()
->toArray();
->whereBetween("end_at", [
Carbon::now()->addMinutes($hours2 * 60 + 3),
Carbon::now()->addMinutes($hours2 * 60 - 3)
])->chunkById(100, function ($tasks) {
/** @var ProjectTask $task */
foreach ($tasks as $task) {
$this->overdueBeforeAfterEmail($task, false);
}
});
}
$taskLists = array_merge($taskLists1, $taskLists2);
$ids = [];
foreach ($taskLists as $task) {
if (!in_array($task->id, $ids)) {
$ids[] = $task->id;
ProjectTask::overdueRemindEmail($task);
}
}

/**
* 过期前、超期后提醒
* @param ProjectTask $task
* @param $isBefore
* @return void
*/
private function overdueBeforeAfterEmail(ProjectTask $task, $isBefore)
{
$userids = $task->taskUser->where('owner', 1)->pluck('userid')->toArray();
if (empty($userids)) {
return;
}
$users = User::whereIn('userid', $userids)->get();
if (empty($users)) {
return;
}

$setting = Base::setting('emailSetting');
$hours = floatval($setting['task_remind_hours']);
$hours2 = floatval($setting['task_remind_hours2']);
if ($isBefore) {
$subject = "任务提醒";
$content = "<p>用户您好, " . env('APP_NAME') . " 任务到期提醒。</p><p>您有一个任务【{{$task->name}}】还有{{$hours}}小时即将超时,请及时处理</p>";
} else {
$subject = "任务过期提醒";
$content = "<p>用户您好, " . env('APP_NAME') . " 任务到期提醒。</p><p>您的任务【{{$task->name}}】已经超时{{$hours2}}小时,请及时处理</p>";
}

/** @var User $user */
foreach ($users as $user) {
$data = [
'type' => $isBefore ? 1 : 2,
'userid' => $user->userid,
'task_id' => $task->id,
];
$emailLog = ProjectTaskMailLog::where($data)->first();
if ($emailLog) {
continue;
}
try {
if (!Base::isEmail($user->email)) {
throw new \Exception("User email '{$user->email}' address error");
}
Factory::mailer()
->setDsn("smtp://{$setting['account']}:{$setting['password']}@{$setting['smtp_server']}:{$setting['port']}?verify_peer=0")
->setMessage(EmailMessage::create()
->from(env('APP_NAME', 'Task') . " <{$setting['account']}>")
->to($user->email)
->subject($subject)
->html($content))
->send();
$data['is_send'] = 1;
} catch (\Exception $e) {
$data['send_error'] = $e->getMessage();
}
$data['email'] = $user->email;
ProjectTaskMailLog::createInstance($data)->save();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddProjectTaskMailLogsSendError extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('project_task_mail_logs', function (Blueprint $table) {
if (!Schema::hasColumn('project_task_mail_logs', 'send_error')) {
$table->text('send_error')->nullable()->after('is_send')->comment('邮件发送错误详情');
}
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('project_task_mail_logs', function (Blueprint $table) {
$table->dropColumn("send_error");
});
}
}
19 changes: 0 additions & 19 deletions resources/views/taskOverdueRemind.blade.php

This file was deleted.

0 comments on commit 601d037

Please sign in to comment.