parent
ecf9758d64
commit
bd580f4093
@ -0,0 +1,80 @@ |
||||
<?php |
||||
|
||||
namespace App\Console\Commands; |
||||
|
||||
use App\Dictionary\SendMessage\Type; |
||||
use App\Dictionary\WeChat\MiniProgram\SubscribeId; |
||||
use App\Jobs\SendWeChatMessageJob; |
||||
use App\Models\RegistrationRecord; |
||||
use App\Models\SendMessageJob; |
||||
use App\Utils\Traits\SendSubscribeMessage; |
||||
use Exception; |
||||
use Illuminate\Console\Command; |
||||
use Illuminate\Support\Facades\Log; |
||||
use \Symfony\Component\Console\Command\Command as BaseCommand; |
||||
use Throwable; |
||||
|
||||
/** |
||||
* Appointment Visit Reminders 发送预约就诊提示 |
||||
* @example |
||||
*/ |
||||
class SendAppointmentReminders extends Command |
||||
{ |
||||
use SendSubscribeMessage; |
||||
|
||||
/** |
||||
* The name and signature of the console command. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $signature = 'app:send-appointment-reminders'; |
||||
|
||||
/** |
||||
* The console command description. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $description = 'Send appointment reminders to users via WeChat subscription messages'; |
||||
|
||||
/** |
||||
* Execute the console command. |
||||
*/ |
||||
public function handle(): int |
||||
{ |
||||
$this->info('Starting to send appointment reminders...'); |
||||
|
||||
// 查询即将到期的预约记录(8小时后的预约) |
||||
$appointments = RegistrationRecord::where('visit_date', now()->toDate()) |
||||
->where('begin_date', now()->subHours(8)) |
||||
->where('reminder_sent', 0) |
||||
->get(); |
||||
|
||||
if ($appointments->isEmpty()) { |
||||
$this->info('No appointments to send reminders for.'); |
||||
return BaseCommand::SUCCESS; |
||||
} |
||||
|
||||
$message = new SendMessageJob(); |
||||
$success_records = []; |
||||
foreach ($appointments as $appointment) { |
||||
try { |
||||
$this->sendAppointmentReminderMessage($appointment); |
||||
|
||||
// 标记提醒已发送 |
||||
$appointment->update(['reminder_sent' => 1]); |
||||
$success_records[] = $appointment->id; |
||||
|
||||
$this->info("Reminder sent for appointment ID: {$appointment->id}"); |
||||
Log::channel('send_wechat_message')->info('Reminder sent for appointment ID: '. $appointment->id); |
||||
} catch (Exception|Throwable $e) { |
||||
// 记录错误日志 |
||||
$err_msg = "{$e->getMessage()} ON {$e->getFile()}:{$e->getLine()}"; |
||||
$this->error("Failed to send reminder for appointment ID: {$appointment->id}, Err msg: {$err_msg}"); |
||||
Log::channel('send_wechat_message')->error('Failed to send reminder for appointment ID: '. $appointment->id, ['error' => $err_msg]); |
||||
} |
||||
} |
||||
|
||||
$this->info( '['. date('Y-m-d H:i:s').'] Appointment reminders sent successfully. send Record:'. implode(',', $success_records)); |
||||
return BaseCommand::SUCCESS; |
||||
} |
||||
} |
@ -1,51 +0,0 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Dictionary\PushMessage; |
||||
|
||||
use App\Dictionary\WeChat\Official\OpenApi; |
||||
|
||||
/** |
||||
* 推送微信消息类型 |
||||
*/ |
||||
enum Type: int |
||||
{ |
||||
case OFFICIAL_TEMPLATE = 1; |
||||
|
||||
case OFFICIAL_SINGLE_SUBSCRIBE = 2; |
||||
|
||||
case OFFICIAL_SUBSCRIBE = 3; |
||||
|
||||
case OFFICIAL_CUSTOM = 4; |
||||
|
||||
/** |
||||
* Label string. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function label(): string |
||||
{ |
||||
return match ($this) { |
||||
self::OFFICIAL_TEMPLATE => '公众号模板消息', |
||||
self::OFFICIAL_SINGLE_SUBSCRIBE => '公众号一次性订阅消息', |
||||
self::OFFICIAL_SUBSCRIBE => '公众号订阅消息', |
||||
self::OFFICIAL_CUSTOM => '公众号客服消息', |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Get Open Api. |
||||
* |
||||
* @return OpenApi |
||||
*/ |
||||
public function api(): OpenApi |
||||
{ |
||||
return match ($this) { |
||||
self::OFFICIAL_TEMPLATE => OpenApi::SEND_TEMPLATE_MESSAGE, |
||||
self::OFFICIAL_SINGLE_SUBSCRIBE => OpenApi::SEND_SINGLE_SUBSCRIBE_MESSAGE, |
||||
self::OFFICIAL_SUBSCRIBE => OpenApi::SEND_SUBSCRIBE_MESSAGE, |
||||
self::OFFICIAL_CUSTOM => OpenApi::SEND_CUSTOM_MESSAGE, |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,52 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Dictionary\SendMessage; |
||||
|
||||
use App\Dictionary\WeChat\MiniProgram\OpenApi as MiniOpenApi; |
||||
use App\Dictionary\WeChat\Official\OpenApi as OfficialOpenApi; |
||||
|
||||
/** |
||||
* 推送微信消息类型 |
||||
*/ |
||||
enum Type: int |
||||
{ |
||||
case TEMPLATE = 1; |
||||
|
||||
case SINGLE_SUBSCRIBE = 2; |
||||
|
||||
case SUBSCRIBE = 3; |
||||
|
||||
case CUSTOM = 4; |
||||
|
||||
/** |
||||
* Label string. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function label(): string |
||||
{ |
||||
return match ($this) { |
||||
self::TEMPLATE => '模板消息', |
||||
self::SINGLE_SUBSCRIBE => '一次性订阅消息', |
||||
self::SUBSCRIBE => '长期订阅消息', |
||||
self::CUSTOM => '客服消息', |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Get Open Api. |
||||
* |
||||
* @return OfficialOpenApi|MiniOpenApi |
||||
*/ |
||||
public function api(): OfficialOpenApi|MiniOpenApi |
||||
{ |
||||
return match ($this) { |
||||
self::TEMPLATE => OfficialOpenApi::SEND_TEMPLATE_MESSAGE, |
||||
self::SINGLE_SUBSCRIBE, |
||||
self::SUBSCRIBE => MiniOpenApi::SEND_SUBSCRIBE_MESSAGE, |
||||
self::CUSTOM => OfficialOpenApi::SEND_CUSTOM_MESSAGE, |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,47 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Dictionary\WeChat\MiniProgram; |
||||
|
||||
/** |
||||
* 推送模板消息ID |
||||
*/ |
||||
enum SubscribeId: string |
||||
{ |
||||
|
||||
case PATIENT_BIND_SUCCESS = 'C1JKomPq-Bes7fOs4vv2Jcy5SFUVvnr_qcl9oNaz7eQ'; |
||||
|
||||
case PATIENT_UNBIND_SUCCESS = 'oDOqp-Smyve0Se8ued4592HC82fBxRLodD1CCb2FWBU'; |
||||
|
||||
case REGISTRATION_SUCCESS = '8TEAjsZsuK8atvLeLqzEH067Mnn5qGmyFnshEy6YsiU'; |
||||
|
||||
case REGISTRATION_FAILURE = '4I_LqdovtP1gwkQjH78Y7gwuPde_rY0qgPqNl4aPBWk'; |
||||
|
||||
case REGISTRATION_CANCEL = 'fVaoPnY6MOpKXbpnrGcPqcLl8dv-aRBNfCGeOlgL8bA'; |
||||
|
||||
case OUTPATIENT_PAYMENT_SUCCESS = 'IlYVy2NNv7v6sg-s_Y6OYS4bRlulosztG0fn7LW4qcQ'; |
||||
|
||||
case OUTPATIENT_PAYMENT_FAILURE = 'ayUD7DXCxZAlhWZ7YiWnHvUXf3AqS_6xkWlbCMC40ek'; |
||||
|
||||
case VISIT_REMIND = 'PidheHDjaf--SIu4-wsDT2uFA_0gjDhq_BU0fABa_w0'; |
||||
|
||||
/** |
||||
* Label string |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function label(): string |
||||
{ |
||||
return match ($this) { |
||||
self::PATIENT_BIND_SUCCESS => '就诊人解绑成功提醒', |
||||
self::PATIENT_UNBIND_SUCCESS => '就诊人绑定成功提醒', |
||||
self::REGISTRATION_SUCCESS => '挂号成功通知', |
||||
self::REGISTRATION_FAILURE => '挂号失败通知', |
||||
self::REGISTRATION_CANCEL => '取消预约挂号通知', |
||||
self::OUTPATIENT_PAYMENT_SUCCESS => '门诊缴费成功通知', |
||||
self::OUTPATIENT_PAYMENT_FAILURE => '门诊缴费失败通知', |
||||
self::VISIT_REMIND => '就诊提醒', |
||||
}; |
||||
} |
||||
} |
@ -1,58 +0,0 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Dictionary\WeChat\Official; |
||||
|
||||
/** |
||||
* 推送模板消息ID |
||||
*/ |
||||
enum SubscribeId: string |
||||
{ |
||||
case REGISTRATION_SUCCESS = 'ASUyXyVFONT6RNwbAs49_rHKQUkc_7iXs31kt1AyACU'; |
||||
|
||||
case REGISTRATION_FAILURE = '36fosQYJU-dN8AsNZERrXY9bfEhP1N9zoqVkORnVr_o'; |
||||
|
||||
case REGISTRATION_CANCEL = '8sWThvcSxg0uS6AFy0LWOeGjbRTUI_n2QHDDMYffjGo'; |
||||
|
||||
case OUTPATIENT_PENDING = 'qieeDt7t2XnT0xB8Fc5ec_peuQDN4TQFPl3ivsILKF0'; |
||||
|
||||
case OUTPATIENT_PAYMENT = 'Aeww94Ahcr0q8bGaAQTSW3s6CB2RXdN9qxZV65bYhhc'; |
||||
|
||||
case INPATIENT_RECHARGE_SUCCESS = 'V30A9ZZ6dqJe_DrYhB5YTUmDbj_F99oJ5k3XP4LK7qk'; |
||||
|
||||
case INPATIENT_RECHARGE_FAILURE = '02HnYY5HFP9LKrWDX_UsQNq2vw3ttfGBvZ4H7SfPZyM'; |
||||
|
||||
case REFUND = '3C9Zw6gBgESwciGF3y2ZeoelYXg1fiZeHAnOUXRf2nM'; |
||||
|
||||
case VISIT = 'IrpIcVU20c5GzBPNUqkp_lvuO-t8gxjiiGx7S88GvIA'; |
||||
|
||||
case SUSPEND_VISIT = 'fTUc-MhhqpBA9WzqQQtfceAmgRr8EFuJNDSdvRDG5K8'; |
||||
|
||||
case TAKE_MEDICINE = '-NX91rCEWPejiKVgbkkGf1QF4zNyH7tadHnkTDqyK_c'; |
||||
|
||||
case TODO_LIST = 'pLdQ5HfXP12C8bHM8EiUP2dqOVFqv-2m0YGCpqC-54Y'; |
||||
|
||||
/** |
||||
* Label string |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function label(): string |
||||
{ |
||||
return match ($this) { |
||||
self::REGISTRATION_SUCCESS => '挂号成功通知', |
||||
self::REGISTRATION_FAILURE => '挂号失败通知', |
||||
self::REGISTRATION_CANCEL => '挂号取消通知', |
||||
self::OUTPATIENT_PENDING => '门诊待缴费通知', |
||||
self::OUTPATIENT_PAYMENT => '门诊缴费通知', |
||||
self::INPATIENT_RECHARGE_SUCCESS => '住院预交金支付成功通知', |
||||
self::INPATIENT_RECHARGE_FAILURE => '住院预交失败提醒', |
||||
self::REFUND => '退费通知', |
||||
self::VISIT => '就诊提醒', |
||||
self::SUSPEND_VISIT => '医生停诊通知', |
||||
self::TAKE_MEDICINE => '取药通知', |
||||
self::TODO_LIST => '待办事项通知' |
||||
}; |
||||
} |
||||
} |
@ -1,58 +0,0 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Dictionary\WeChat\Official; |
||||
|
||||
/** |
||||
* 推送模板消息ID |
||||
*/ |
||||
enum TemplateId: string |
||||
{ |
||||
case REGISTRATION_SUCCESS = 'ASUyXyVFONT6RNwbAs49_rHKQUkc_7iXs31kt1AyACU'; |
||||
|
||||
case REGISTRATION_FAILURE = '36fosQYJU-dN8AsNZERrXY9bfEhP1N9zoqVkORnVr_o'; |
||||
|
||||
case REGISTRATION_CANCEL = '8sWThvcSxg0uS6AFy0LWOeGjbRTUI_n2QHDDMYffjGo'; |
||||
|
||||
case OUTPATIENT_PENDING = 'qieeDt7t2XnT0xB8Fc5ec_peuQDN4TQFPl3ivsILKF0'; |
||||
|
||||
case OUTPATIENT_PAYMENT = 'Aeww94Ahcr0q8bGaAQTSW3s6CB2RXdN9qxZV65bYhhc'; |
||||
|
||||
case INPATIENT_RECHARGE_SUCCESS = 'V30A9ZZ6dqJe_DrYhB5YTUmDbj_F99oJ5k3XP4LK7qk'; |
||||
|
||||
case INPATIENT_RECHARGE_FAILURE = '02HnYY5HFP9LKrWDX_UsQNq2vw3ttfGBvZ4H7SfPZyM'; |
||||
|
||||
case REFUND = '3C9Zw6gBgESwciGF3y2ZeoelYXg1fiZeHAnOUXRf2nM'; |
||||
|
||||
case VISIT = 'IrpIcVU20c5GzBPNUqkp_lvuO-t8gxjiiGx7S88GvIA'; |
||||
|
||||
case SUSPEND_VISIT = 'fTUc-MhhqpBA9WzqQQtfceAmgRr8EFuJNDSdvRDG5K8'; |
||||
|
||||
case TAKE_MEDICINE = '-NX91rCEWPejiKVgbkkGf1QF4zNyH7tadHnkTDqyK_c'; |
||||
|
||||
case TODO_LIST = 'pLdQ5HfXP12C8bHM8EiUP2dqOVFqv-2m0YGCpqC-54Y'; |
||||
|
||||
/** |
||||
* Label string |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function label(): string |
||||
{ |
||||
return match ($this) { |
||||
self::REGISTRATION_SUCCESS => '挂号成功通知', |
||||
self::REGISTRATION_FAILURE => '挂号失败通知', |
||||
self::REGISTRATION_CANCEL => '挂号取消通知', |
||||
self::OUTPATIENT_PENDING => '门诊待缴费通知', |
||||
self::OUTPATIENT_PAYMENT => '门诊缴费通知', |
||||
self::INPATIENT_RECHARGE_SUCCESS => '住院预交金支付成功通知', |
||||
self::INPATIENT_RECHARGE_FAILURE => '住院预交失败提醒', |
||||
self::REFUND => '退费通知', |
||||
self::VISIT => '就诊提醒', |
||||
self::SUSPEND_VISIT => '医生停诊通知', |
||||
self::TAKE_MEDICINE => '取药通知', |
||||
self::TODO_LIST => '待办事项通知' |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Jobs\Message; |
||||
|
||||
use App\Dictionary\SendMessage\Type as MessageType; |
||||
use EasyWeChat\Kernel\HttpClient\Response; |
||||
use EasyWeChat\OfficialAccount\Application as OfficialApplication; |
||||
use EasyWeChat\MiniApp\Application as MiniApplication; |
||||
use EasyWeChat\Work\Application as WorkApplication; |
||||
use Illuminate\Support\Facades\Log; |
||||
use ReflectionException; |
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; |
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; |
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; |
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; |
||||
|
||||
abstract class Message |
||||
{ |
||||
/** |
||||
* @return OfficialApplication|MiniApplication|WorkApplication |
||||
*/ |
||||
abstract public function getApp(): OfficialApplication|MiniApplication|WorkApplication; |
||||
|
||||
/** |
||||
* Send Message. |
||||
* |
||||
* @param MessageType $type 消息类型 |
||||
* @param array $message 消息数据 json 包 |
||||
* |
||||
* @return Response |
||||
* |
||||
* @throws TransportExceptionInterface |
||||
* @throws ClientExceptionInterface |
||||
* @throws RedirectionExceptionInterface |
||||
* @throws ServerExceptionInterface |
||||
*/ |
||||
public function send(MessageType $type, array $message): Response |
||||
{ |
||||
/** @var Response $response */ |
||||
$response = $this->getApp()->getClient()->postJson($type->api()->value, $message); |
||||
|
||||
Log::channel('SendWeChatMessage')->info('Push WeChat Message', [$type->label(), $message, $response->getContent(false)]); |
||||
|
||||
return $response; |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Jobs\Message; |
||||
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException; |
||||
use EasyWeChat\MiniApp\Application as MiniApplication; |
||||
|
||||
class SubscriptionMessage extends Message |
||||
{ |
||||
/** |
||||
* @return MiniApplication |
||||
* @throws InvalidArgumentException |
||||
*/ |
||||
public function getApp(): MiniApplication |
||||
{ |
||||
/** @var MiniApplication */ |
||||
return getWeChatMiniProgramApp(); |
||||
} |
||||
} |
@ -0,0 +1,159 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Jobs; |
||||
|
||||
use App\Dictionary\SendMessage\Type as MessageType; |
||||
use App\Dictionary\SendMessage\Status as MessageStatus; |
||||
use App\Jobs\Message\SubscriptionMessage; |
||||
use App\Models\SendMessageJob; |
||||
use Exception; |
||||
use Illuminate\Bus\Queueable; |
||||
use Illuminate\Contracts\Cache\Repository; |
||||
use Illuminate\Contracts\Queue\ShouldBeUnique; |
||||
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\Log; |
||||
use Throwable; |
||||
|
||||
class SendWeChatMessageJob implements ShouldQueue, ShouldBeUnique |
||||
{ |
||||
use Dispatchable; |
||||
use InteractsWithQueue; |
||||
use Queueable; |
||||
use SerializesModels; |
||||
|
||||
/** |
||||
* PushWechatMessage Model. |
||||
* |
||||
* @var SendMessageJob |
||||
*/ |
||||
protected SendMessageJob $message; |
||||
|
||||
/** |
||||
* Message Type. |
||||
* |
||||
* @var MessageType |
||||
*/ |
||||
protected MessageType $message_type; |
||||
|
||||
/** |
||||
* 任务可尝试次数. |
||||
* |
||||
* @var int |
||||
*/ |
||||
public int $tries = 3; |
||||
|
||||
/** |
||||
* 任务的唯一 ID。 |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function uniqueId(): string |
||||
{ |
||||
return 'Queue:SendWechatMessage:'. $this->message->id; |
||||
} |
||||
|
||||
/** |
||||
* 获取唯一任务锁的缓存驱动程序。 |
||||
* |
||||
* @return Repository |
||||
*/ |
||||
public function uniqueVia(): Repository |
||||
{ |
||||
return Cache::driver('redis'); |
||||
} |
||||
|
||||
/** |
||||
* Send WeChat Message Job Construct. |
||||
* |
||||
* @param SendMessageJob $message |
||||
*/ |
||||
public function __construct(SendMessageJob $message) |
||||
{ |
||||
$this->message = $message->withoutRelations(); |
||||
$this->message_type = MessageType::from($this->message->type); |
||||
} |
||||
|
||||
/** |
||||
* Execute the job. |
||||
*/ |
||||
public function handle(): void |
||||
{ |
||||
$content = json_decode($this->message->content, true); |
||||
|
||||
try { |
||||
$response = match ($this->message_type) { |
||||
MessageType::TEMPLATE, |
||||
MessageType::SINGLE_SUBSCRIBE, |
||||
MessageType::SUBSCRIBE, |
||||
MessageType::CUSTOM => (new SubscriptionMessage())->send($this->message_type, $content), |
||||
}; |
||||
|
||||
$data = $response->toArray(false); |
||||
|
||||
if ($response->isSuccessful()) { |
||||
$this->successful((string)$data['errcode']); |
||||
} else { |
||||
$this->retry((string)$data['errmsg']); |
||||
} |
||||
|
||||
} catch (Exception|Throwable $e) { |
||||
$message = $e->getMessage().' in '.$e->getFile().':'.$e->getLine(); |
||||
Log::channel('SendWeChatMessage')->info('Push WeChat Message Error', [$this->message->id, $message]); |
||||
|
||||
$this->retry($e->getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Handle a job successful. |
||||
* |
||||
* @param string $msg_id |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function successful(string $msg_id): void |
||||
{ |
||||
$this->message->status = MessageStatus::SUCCESS->value; |
||||
$this->message->msg_id = $msg_id; |
||||
$this->message->sent_at = date('Y-m-d H:i:s'); |
||||
$this->message->save(); |
||||
} |
||||
|
||||
/** |
||||
* Handle a job retry. |
||||
* |
||||
* @param string $fail_reason |
||||
* @return void |
||||
*/ |
||||
public function retry(string $fail_reason): void |
||||
{ |
||||
if ($this->message->number < 3) { |
||||
++$this->message->number; |
||||
$this->message->save(); |
||||
|
||||
$this->release(10); |
||||
} else { |
||||
$this->failed($fail_reason); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Handle a job failure. |
||||
* |
||||
* @param string $fail_reason |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function failed(string $fail_reason): void |
||||
{ |
||||
$this->message->status = MessageStatus::FAILURE->value; |
||||
$this->message->fail_reason = $fail_reason; |
||||
$this->message->save(); |
||||
} |
||||
} |
@ -0,0 +1,260 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Utils\Traits; |
||||
use App\Dictionary\SendMessage\Type; |
||||
use App\Dictionary\WeChat\MiniProgram\SubscribeId; |
||||
use App\Jobs\SendWeChatMessageJob; |
||||
use App\Models\Order as OrderModel; |
||||
use App\Models\RegistrationRecord; |
||||
use App\Models\SendMessageJob; |
||||
|
||||
trait SendSubscribeMessage |
||||
{ |
||||
|
||||
protected static SendMessageJob $message_model; |
||||
|
||||
/** |
||||
* 单例获取 SendMessageJob |
||||
* @return SendMessageJob |
||||
*/ |
||||
public static function getSendMessageJob(): SendMessageJob |
||||
{ |
||||
if (!self::$message_model) { |
||||
self::$message_model = new SendMessageJob(); |
||||
} |
||||
return self::$message_model; |
||||
} |
||||
|
||||
/** |
||||
* 发送绑定患者订阅消息 |
||||
* @param string $open_id |
||||
* @param int $relate_patient_id |
||||
* @param string $patient_name |
||||
* @return void |
||||
*/ |
||||
public function sendBindPatientSubscribeMessage(string $open_id, int $relate_patient_id, string $patient_name): void |
||||
{ |
||||
$subscribe_id = SubscribeId::PATIENT_BIND_SUCCESS; |
||||
$data = [ |
||||
'touser' => $open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => 'pagesA/card/index', |
||||
'data' => [ |
||||
'thing1' => ['value' => $patient_name], |
||||
'time2' => ['value' => date('Y-m-d H:i')], |
||||
'thing3' => ['value' => '您已绑定成功,可以进行线上线下就医服务。'], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送绑定患者订阅消息 |
||||
* @param string $open_id |
||||
* @param int $relate_patient_id |
||||
* @param string $patient_name |
||||
* @param string $inpatient_id 住院号 |
||||
* @param string $patient_id 门诊号 |
||||
* @return void |
||||
*/ |
||||
public function sendUnbindPatientSubscribeMessage(string $open_id, int $relate_patient_id, string $patient_name, string $inpatient_id, string $patient_id): void |
||||
{ |
||||
$subscribe_id = SubscribeId::PATIENT_UNBIND_SUCCESS; |
||||
$data = [ |
||||
'touser' => $open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => '', |
||||
'data' => [ |
||||
'thing1' => ['value' => $patient_name], |
||||
'time2' => ['value' => date('Y-m-d H:i')], |
||||
'thing3' => ['value' => '您已解除绑定关系,无法使用线上线下就医服务。'], |
||||
'character_string5' => ['value' => $inpatient_id], |
||||
'character_string6' => ['value' => $patient_id], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送就诊提醒消息 |
||||
* @param RegistrationRecord $record |
||||
* @return void |
||||
*/ |
||||
public function sendAppointmentReminderMessage(RegistrationRecord $record): void |
||||
{ |
||||
$order = &$record->order; |
||||
$subscribe_id = SubscribeId::VISIT_REMIND; |
||||
$visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; |
||||
$data = [ |
||||
'touser' => $order->open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => 'pagesA/register/regRecord', |
||||
'data' => [ |
||||
'name1' => ['value' => $order->patient_name], |
||||
'time7' => ['value' => $visit_time], |
||||
'thing10' => ['value' => $record->dept_name. '('. $record->doctor_name. ')'], |
||||
'thing6' => ['value' => $record->dept_location], |
||||
'thing5' => ['value' => '请准时前往医院就诊。'], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送挂号成功订阅消息 |
||||
* @param OrderModel $order |
||||
* @return void |
||||
*/ |
||||
public function sendRegistrationSuccessMessage(OrderModel $order): void |
||||
{ |
||||
$record = &$order->registrationRecord; |
||||
$subscribe_id = SubscribeId::REGISTRATION_SUCCESS; |
||||
$visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; |
||||
$data = [ |
||||
'touser' => $order->open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => 'pagesA/register/regRecord', |
||||
'data' => [ |
||||
'thing5' => ['value' => $record->dept_name], |
||||
'thing17' => ['value' => $record->dept_location], |
||||
'character_string15' => ['value' => $visit_time], |
||||
'thing19' => ['value' => $record->doctor_name], |
||||
'amount13' => ['value' => $order->fee / 100], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送挂号失败订阅消息 |
||||
* @param OrderModel $order |
||||
* @return void |
||||
*/ |
||||
public function sendRegistrationFailureMessage(OrderModel $order): void |
||||
{ |
||||
$record = &$order->registrationRecord; |
||||
$subscribe_id = SubscribeId::REGISTRATION_FAILURE; |
||||
$visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; |
||||
$data = [ |
||||
'touser' => $order->open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => 'pagesA/register/regRecord', |
||||
'data' => [ |
||||
'thing2' => ['value' => $record->dept_name], |
||||
'thing3' => ['value' => $record->doctor_name], |
||||
'name1' => ['value' => $order->patient_name], |
||||
'time4' => ['value' => $visit_time], |
||||
'amount13' => ['value' => $order->fee / 100], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送取消预约挂号消息 |
||||
* @param OrderModel $order |
||||
* @return void |
||||
*/ |
||||
public function sendRegistrationCancelMessage(OrderModel $order): void |
||||
{ |
||||
$record = &$order->registrationRecord; |
||||
$subscribe_id = SubscribeId::REGISTRATION_CANCEL; |
||||
$visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; |
||||
$data = [ |
||||
'touser' => $order->open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => 'pagesA/register/regRecord', |
||||
'data' => [ |
||||
'thing1' => ['value' => $order->patient_name], |
||||
'thing2' => ['value' => $record->dept_name], |
||||
'thing3' => ['value' => $record->doctor_name], |
||||
'time4' => ['value' => $visit_time], |
||||
'thing5' => ['value' => '已成功取消预约,如有需要请重新预约。'], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送门诊缴费成功消息 |
||||
* @param OrderModel $order |
||||
* @return void |
||||
*/ |
||||
public function sendOutpatientPaymentSuccessMessage(OrderModel $order): void |
||||
{ |
||||
$record = &$order->outpatientPaymentRecord; |
||||
$subscribe_id = SubscribeId::OUTPATIENT_PAYMENT_SUCCESS; |
||||
$data = [ |
||||
'touser' => $order->open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => 'pagesA/outpatient/outPayList', |
||||
'data' => [ |
||||
'date5' => ['value' => date('Y-m-d')], |
||||
'amount6' => ['value' => $order->fee / 100], |
||||
'character_string7' => ['value' => $order->order_id], |
||||
'character_string14' => ['value' => $order->patient_id], |
||||
'thing9' => ['value' => '门诊缴费'], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
|
||||
/** |
||||
* 发送门诊缴费失败消息 |
||||
* @param OrderModel $order |
||||
* @return void |
||||
*/ |
||||
public function sendOutpatientPaymentFailureMessage(OrderModel $order): void |
||||
{ |
||||
$record = &$order->outpatientPaymentRecord; |
||||
$subscribe_id = SubscribeId::OUTPATIENT_PAYMENT_FAILURE; |
||||
$data = [ |
||||
'touser' => $order->open_id, |
||||
'template_id' => $subscribe_id->value, |
||||
'page' => '', |
||||
'data' => [ |
||||
|
||||
'character_string1' => ['value' => $order->order_id], |
||||
'thing2' => ['value' => '门诊缴费'], |
||||
'name3' => ['value' => $order->patient_name], |
||||
'amount4' => ['value' => $order->fee / 100], |
||||
'date6' => ['value' => date('Y-m-d')], |
||||
], |
||||
'miniprogram_state' => env('custom.mini_program_message_state') |
||||
]; |
||||
|
||||
$message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); |
||||
|
||||
SendWeChatMessageJob::dispatch($message); |
||||
} |
||||
} |
@ -1,33 +0,0 @@ |
||||
<?php |
||||
|
||||
use Illuminate\Database\Migrations\Migration; |
||||
use Illuminate\Database\Schema\Blueprint; |
||||
use Illuminate\Support\Facades\Schema; |
||||
|
||||
return new class extends Migration |
||||
{ |
||||
/** |
||||
* Run the migrations. |
||||
*/ |
||||
public function up(): void |
||||
{ |
||||
Schema::create('personal_access_tokens', function (Blueprint $table) { |
||||
$table->id(); |
||||
$table->morphs('tokenable'); |
||||
$table->string('name'); |
||||
$table->string('token', 64)->unique(); |
||||
$table->text('abilities')->nullable(); |
||||
$table->timestamp('last_used_at')->nullable(); |
||||
$table->timestamp('expires_at')->nullable(); |
||||
$table->timestamps(); |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Reverse the migrations. |
||||
*/ |
||||
public function down(): void |
||||
{ |
||||
Schema::dropIfExists('personal_access_tokens'); |
||||
} |
||||
}; |
Loading…
Reference in new issue