You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ss-visit/app/Console/Commands/SendVisitReminderCommand.php

129 lines
4.5 KiB

11 months ago
<?php
namespace App\Console\Commands;
use App\Models\Visit;
use App\Models\VisitLog;
use App\Notifications\SmsNotify;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
class SendVisitReminderCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'visit:reminder {--time=18:00 : 提醒时间默认18:00}';
/**
* The console command description.
*
* @var string
*/
protected $description = '发送未核销拜访预约提醒';
/**
* Execute the console command.
*/
public function handle()
{
$reminderTime = $this->option('time');
$currentTime = Carbon::now();
// 检查是否到了提醒时间
if ($currentTime->format('H:i') !== $reminderTime) {
$this->info("当前时间 {$currentTime->format('H:i')} 不是提醒时间 {$reminderTime},跳过执行");
return;
}
$this->info("开始检查未核销的拜访预约...");
try {
// 获取当天18:00后仍未核销的预约记录
$unusedVisits = Visit::with(['visitArea', 'visitTime', 'acceptAdmin'])
->whereDate('date', Carbon::today())
->where('audit_status', Visit::AUDIT_STATUS_APPROVED) // 已审核通过但未进厂
->where(function ($query) use ($currentTime) {
// 18:00后的记录
$query->whereHas('visitTime', function ($q) use ($currentTime) {
$q->where('end_time', '<=', $currentTime->format('H:i:s'));
});
})
->get();
if ($unusedVisits->isEmpty()) {
$this->info('没有需要提醒的未核销预约记录');
return;
}
$this->info("找到 {$unusedVisits->count()} 条未核销的预约记录");
foreach ($unusedVisits as $visit) {
$this->sendReminder($visit);
}
$this->info('提醒发送完成');
} catch (\Exception $e) {
Log::error('发送拜访提醒失败:' . $e->getMessage());
$this->error('发送提醒失败:' . $e->getMessage());
}
}
/**
* 发送提醒
*/
private function sendReminder(Visit $visit)
{
try {
// 记录提醒日志
VisitLog::log($visit->id, VisitLog::TYPE_UPDATE, "系统自动提醒:访客 {$visit->name} 预约时间已过,请及时核销");
// 构建提醒消息
$message = "【访客系统提醒】访客 {$visit->name}{$visit->mobile})的预约时间已过,请及时核销。预约编号:{$visit->code}";
// 发送短信提醒给接待人员
if ($visit->acceptAdmin && $visit->acceptAdmin->mobile) {
$this->sendSmsReminder($visit->acceptAdmin->mobile, $message);
$this->info("已发送短信提醒给接待人员:{$visit->acceptAdmin->name}");
}
// 发送短信提醒给访客
if ($visit->mobile) {
$visitorMessage = "【访客系统提醒】您的预约时间已过,请及时联系接待人员。预约编号:{$visit->code}";
$this->sendSmsReminder($visit->mobile, $visitorMessage);
$this->info("已发送短信提醒给访客:{$visit->name}");
}
$this->info("已处理访客:{$visit->name}{$visit->code}");
} catch (\Exception $e) {
Log::error("发送访客 {$visit->name} 提醒失败:" . $e->getMessage());
$this->error("发送访客 {$visit->name} 提醒失败:" . $e->getMessage());
}
}
/**
* 发送短信提醒
*/
private function sendSmsReminder($mobile, $message)
{
try {
// 这里可以集成实际的短信发送服务
// 例如:阿里云短信、腾讯云短信等
Log::info("发送短信提醒到 {$mobile}{$message}");
// 模拟短信发送
$this->info("模拟发送短信到 {$mobile}{$message}");
// 实际项目中可以这样发送:
// $smsNotify = new SmsNotify($message);
// Notification::route('sms', $mobile)->notify($smsNotify);
} catch (\Exception $e) {
Log::error("发送短信到 {$mobile} 失败:" . $e->getMessage());
throw $e;
}
}
}