diff --git a/app/Console/Commands/SendAppointmentReminders.php b/app/Console/Commands/SendAppointmentReminders.php new file mode 100644 index 0000000..2745020 --- /dev/null +++ b/app/Console/Commands/SendAppointmentReminders.php @@ -0,0 +1,80 @@ +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; + } +} diff --git a/app/Dictionary/PushMessage/Type.php b/app/Dictionary/PushMessage/Type.php deleted file mode 100644 index cbdfd19..0000000 --- a/app/Dictionary/PushMessage/Type.php +++ /dev/null @@ -1,51 +0,0 @@ - '公众号模板消息', - 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, - }; - } -} diff --git a/app/Dictionary/PushMessage/Status.php b/app/Dictionary/SendMessage/Status.php similarity index 92% rename from app/Dictionary/PushMessage/Status.php rename to app/Dictionary/SendMessage/Status.php index 2535b7f..fc5f535 100644 --- a/app/Dictionary/PushMessage/Status.php +++ b/app/Dictionary/SendMessage/Status.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Dictionary\PushMessage; +namespace App\Dictionary\SendMessage; use App\Dictionary\WeChat\Official\OpenApi; diff --git a/app/Dictionary/SendMessage/Type.php b/app/Dictionary/SendMessage/Type.php new file mode 100644 index 0000000..5e7705d --- /dev/null +++ b/app/Dictionary/SendMessage/Type.php @@ -0,0 +1,52 @@ + '模板消息', + 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, + }; + } +} diff --git a/app/Dictionary/WeChat/MiniProgram/OpenApi.php b/app/Dictionary/WeChat/MiniProgram/OpenApi.php index df0559f..dc3a13e 100644 --- a/app/Dictionary/WeChat/MiniProgram/OpenApi.php +++ b/app/Dictionary/WeChat/MiniProgram/OpenApi.php @@ -30,4 +30,7 @@ enum OpenApi: string case GET_PAID_UNION_ID = '/wxa/getpaidunionid'; case GET_PHONE_NUMBER = '/wxa/business/getuserphonenumber'; + + // 推送消息 + case SEND_SUBSCRIBE_MESSAGE = 'cgi-bin/message/subscribe/send'; } diff --git a/app/Dictionary/WeChat/MiniProgram/SubscribeId.php b/app/Dictionary/WeChat/MiniProgram/SubscribeId.php new file mode 100644 index 0000000..d270928 --- /dev/null +++ b/app/Dictionary/WeChat/MiniProgram/SubscribeId.php @@ -0,0 +1,47 @@ + '就诊人解绑成功提醒', + self::PATIENT_UNBIND_SUCCESS => '就诊人绑定成功提醒', + self::REGISTRATION_SUCCESS => '挂号成功通知', + self::REGISTRATION_FAILURE => '挂号失败通知', + self::REGISTRATION_CANCEL => '取消预约挂号通知', + self::OUTPATIENT_PAYMENT_SUCCESS => '门诊缴费成功通知', + self::OUTPATIENT_PAYMENT_FAILURE => '门诊缴费失败通知', + self::VISIT_REMIND => '就诊提醒', + }; + } +} diff --git a/app/Dictionary/WeChat/Official/SubscribeId.php b/app/Dictionary/WeChat/Official/SubscribeId.php deleted file mode 100644 index 1e92559..0000000 --- a/app/Dictionary/WeChat/Official/SubscribeId.php +++ /dev/null @@ -1,58 +0,0 @@ - '挂号成功通知', - 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 => '待办事项通知' - }; - } -} diff --git a/app/Dictionary/WeChat/Official/TemplateId.php b/app/Dictionary/WeChat/Official/TemplateId.php deleted file mode 100644 index 274fdd1..0000000 --- a/app/Dictionary/WeChat/Official/TemplateId.php +++ /dev/null @@ -1,58 +0,0 @@ - '挂号成功通知', - 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 => '待办事项通知' - }; - } -} diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 40ada7f..da5141a 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -10,11 +10,6 @@ use App\Http\Requests\Auth\LoginRequest; use Illuminate\Auth\AuthenticationException; use Illuminate\Http\JsonResponse; use Symfony\Component\HttpFoundation\Response; -use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; -use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; -use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; -use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; -use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; class AuthController extends Controller { diff --git a/app/Http/Logics/Dictionary/ItemLogic.php b/app/Http/Logics/Dictionary/ItemLogic.php index 7e68628..19efcc7 100644 --- a/app/Http/Logics/Dictionary/ItemLogic.php +++ b/app/Http/Logics/Dictionary/ItemLogic.php @@ -36,8 +36,8 @@ class ItemLogic public function getLists() { $response = $this->his_client->getDictionaryLists(); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { - throw new GeneralException($response['ERRORMSG'] ?? '找不到缴费项目分类列表!', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '找不到缴费项目分类列表!', Response::HTTP_SERVICE_UNAVAILABLE); } return $response; @@ -52,8 +52,8 @@ class ItemLogic public function getDetails(int $type_id): array { $response = $this->his_client->getDictionaryDetails($type_id); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { - throw new GeneralException($response['ERRORMSG'] ?? '找不到缴费项目分类详情!', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '找不到缴费项目分类详情!', Response::HTTP_SERVICE_UNAVAILABLE); } return $response; diff --git a/app/Http/Logics/Notify/NotifyLogic.php b/app/Http/Logics/Notify/NotifyLogic.php index ec1cf90..72de1cc 100644 --- a/app/Http/Logics/Notify/NotifyLogic.php +++ b/app/Http/Logics/Notify/NotifyLogic.php @@ -15,6 +15,7 @@ use App\Models\Patient as PatientModel; use App\Services\HisHttp\Client; use App\Utils\Traits\Logger; use App\Utils\Traits\RedisLockUtil; +use App\Utils\Traits\SendSubscribeMessage; use EasyWeChat\Kernel\Exceptions\InvalidArgumentException; use EasyWeChat\Kernel\Exceptions\InvalidConfigException; use EasyWeChat\Pay\Application as PaymentApplication; @@ -32,6 +33,7 @@ class NotifyLogic { use Logger; use RedisLockUtil; + use SendSubscribeMessage; protected Client $his_client; @@ -151,16 +153,19 @@ class NotifyLogic $this->unifyConfirm($notify['out_trade_no'], $response['VISITNO'], $notify['openid'], $notify['transaction_id']); // 推送成功 + $this->sendRegistrationSuccessMessage($order_info); } else if (isset($response['RESULTCODE'])) { // 失败流程 $this->handleOrderReverse($order_info, $response['ERRORMSG'] ?? ''); // 推送失败 + $this->sendRegistrationFailureMessage($order_info); } else { // 异常流程 $order_info->abnormalOrderOpera($order_info->id); // 推送异常 + $this->sendRegistrationFailureMessage($order_info); } } @@ -202,19 +207,19 @@ class NotifyLogic $this->unifyConfirm($notify['out_trade_no'], $response['HOSTRANNO'], $notify['openid'], $notify['transaction_id']); // 推送成功 - + $this->sendOutpatientPaymentSuccessMessage($order_info); } else if (isset($response['ResultCode'])) { // 失败流程 $this->handleOrderReverse($order_info, $response['ERRORMSG']); // 推送失败 - + $this->sendOutpatientPaymentFailureMessage($order_info); } else { // 异常流程 $order_info->abnormalOrderOpera($order_info->id); // 推送异常 - + $this->sendOutpatientPaymentFailureMessage($order_info); } } @@ -257,6 +262,7 @@ class NotifyLogic $refund_order_id = $order_info->getRefundOrderId($order_info->order_id); $order_info->createRefundOReverseOrder( $order_info->id, + $order_info->relate_patient_id, $refund_order_id, PayType::from($order_info->pay_type), $order_info->fee, diff --git a/app/Http/Logics/Outpatient/PaymentLogic.php b/app/Http/Logics/Outpatient/PaymentLogic.php index 174de05..f1027d5 100644 --- a/app/Http/Logics/Outpatient/PaymentLogic.php +++ b/app/Http/Logics/Outpatient/PaymentLogic.php @@ -68,7 +68,7 @@ class PaymentLogic $order = $this->createOrder($order_id, $pay_type, $total_fee, $order_type, $patient_info, $pending_info); // 申请支付 - $pay_data = $this->applyPayment($order_type, $order_id, $total_fee, $patient_info['PATIENTID'], $patient_info['NAME']); + $pay_data = $this->applyPayment($order_type, $order_id, $total_fee, $patient_info['patientNumber'], $patient_info['name']); // 去除无用数据 unset($pay_data['merchantId'], $pay_data['merchantName'], $pay_data['channelId'], $pay_data['channelName']); @@ -91,11 +91,12 @@ class PaymentLogic } $patient_info = $this->his_client->getPatientInfo($info['patient_id'], CardType::OUTPATIENT_NO, $info['name']); - if (!isset($patient_info['RESULTCODE']) || $patient_info['RESULTCODE'] !== '0') { - throw new GeneralException($patient_info['ERRORMSG'] ?? '找不到患者信息,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($patient_info['success']) || !$patient_info['success']) { + throw new GeneralException($patient_info['msg'] ?? '找不到患者信息,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } // 添加Patient 表ID + $patient_info = &$response['response']; $patient_info['id'] = $info['id']; $this->info('缴费患者信息', $patient_info); @@ -174,6 +175,7 @@ class PaymentLogic } $order = $this->order_model->createOrder( + $patient_info['id'], $order_id, $pay_type, $total_fee * 100, diff --git a/app/Http/Logics/Patient/PatientLogic.php b/app/Http/Logics/Patient/PatientLogic.php index 291f728..d39151b 100644 --- a/app/Http/Logics/Patient/PatientLogic.php +++ b/app/Http/Logics/Patient/PatientLogic.php @@ -5,11 +5,16 @@ namespace App\Http\Logics\Patient; use App\Dictionary\Patient\CardType; use App\Dictionary\Patient\Sex; +use App\Dictionary\SendMessage\Type; +use App\Dictionary\WeChat\MiniProgram\SubscribeId; use App\Exceptions\GeneralException; +use App\Jobs\SendWeChatMessageJob; use App\Models\Patient; +use App\Models\SendMessageJob; use App\Services\HisHttp\Client; use App\Utils\Traits\Logger; use App\Utils\Traits\MiniProgramAuth; +use App\Utils\Traits\SendSubscribeMessage; use App\Utils\Traits\UniversalEncryption; use Illuminate\Auth\AuthenticationException; use Symfony\Component\HttpFoundation\Response; @@ -19,6 +24,7 @@ class PatientLogic use Logger; use MiniProgramAuth; use UniversalEncryption; + use SendSubscribeMessage; private Client $his_client; @@ -57,13 +63,12 @@ class PatientLogic } // 获取患者信息 - $response = $this->his_client->getPatientInfo($info['patient_id'], CardType::MEDICAL_CARD, $info['name']); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { - throw new GeneralException($response['ERRORMSG'] ?? '找不到该就诊卡!', Response::HTTP_SERVICE_UNAVAILABLE); + $response = $this->his_client->getPatientInfo($info['patient_id'], CardType::OUTPATIENT_NO, $info['name']); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '找不到该就诊卡!', Response::HTTP_SERVICE_UNAVAILABLE); } - $info->patient_card_id = $response['MZHM'] ?? ''; - $info->card_no = substr($response['CARDNO'], 0, 3). '**********'. substr($response['CARDNO'], -3); + $info->birthday = $response['response']['birthday'] ?? ''; return $info; } @@ -115,8 +120,8 @@ class PatientLogic $response = $this->his_client->getPatientInfo($data['card_no'], $card_type, $data['name']); $this->info('查询患者信息:', $response); - if (isset($response['RESULTCODE']) && $response['RESULTCODE'] === '0') { - $patient_id = &$response['PATIENTID']; + if (!isset($response['success']) || !$response['success']) { + $patient_id = &$response['response']['patientNumber']; // 查询是否已绑定 $result = $this->patient_model->getPatientInfoByPatientId($patient_id); @@ -141,13 +146,19 @@ class PatientLogic ); $this->info('建档患者:'. $data['name']. '建档结果', $response); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { - throw new GeneralException('建档失败,失败原因:'. $response['ERRORMSG'] ?? '未知错误', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException('建档失败,失败原因:'. $response['msg'] ?? '未知错误', Response::HTTP_SERVICE_UNAVAILABLE); } + } - $patient_id = &$response['PATIENTID']; + // 再查一遍接口 获取患者信息 + $response = $this->his_client->getPatientInfo($data['card_no'], $card_type, $data['name']); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException('建档失败,失败原因:'. $response['msg'] ?? '未知错误', Response::HTTP_SERVICE_UNAVAILABLE); } + $patient_id = $response['response']['patientNumber']; + // 写入数据库 $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_id, $data['name'], $sex); @@ -155,6 +166,7 @@ class PatientLogic throw new GeneralException('数据保存失败,请重试!', Response::HTTP_INTERNAL_SERVER_ERROR); } + $this->sendBindPatientSubscribeMessage($result->id, $data['name']); return $patient_id; } @@ -180,22 +192,22 @@ class PatientLogic $response = $this->his_client->getPatientInfo($data['card_no'], $card_type, $data['name']); $this->info('查询患者信息:', $response); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] != '0') { - throw new GeneralException($response['ResultContent'] ?? '未知错误'); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '未知错误'); } - $patient_info = &$response; + $patient_info = &$response['response']; $sex = Sex::from((int) $patient_info['SEX']); - if ($patient_info['PATIENTID'] != $data['patient_id']) { + if ($patient_info['patientNumber'] != $data['patient_id']) { throw new GeneralException('该证件号已建档,但就诊卡号不匹配!'); } - if ($patient_info['NAME'] != $data['name']) { + if ($patient_info['name'] != $data['name']) { throw new GeneralException('该证件号已建档,但姓名不匹配!'); } - if ($patient_info['CARDNO'] != $data['card_no']) { + if ($patient_info['cardNo'] != $data['card_no']) { throw new GeneralException('该就诊号已建档,但证件号码不匹配!'); } @@ -210,13 +222,14 @@ class PatientLogic } // 写入数据库 - $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_info['PATIENTID'], $data['name'], $sex); + $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_info['patientNumber'], $data['name'], $sex); if (!$result) { throw new GeneralException('数据保存失败,请重试!', Response::HTTP_INTERNAL_SERVER_ERROR); } - return $patient_info['PATIENTID']; + $this->sendBindPatientSubscribeMessage($this->open_id, $result->id, $data['name']); + return $patient_info['patientNumber']; } /** @@ -258,6 +271,7 @@ class PatientLogic throw new GeneralException('解绑失败,请稍后再试!', Response::HTTP_INTERNAL_SERVER_ERROR); } + $this->sendUnbindPatientSubscribeMessage($this->open_id, $info->id, $info['name'], '', $info['patient_id']); return true; } } diff --git a/app/Http/Logics/Registration/RegisterLogic.php b/app/Http/Logics/Registration/RegisterLogic.php index 51b3536..e505afd 100644 --- a/app/Http/Logics/Registration/RegisterLogic.php +++ b/app/Http/Logics/Registration/RegisterLogic.php @@ -72,7 +72,7 @@ class RegisterLogic $order = $this->createOrder($order_id, $pay_type, $reg_fee, $order_type, $patient_info, $schedule_info); // 申请支付 - $pay_data = $this->applyPayment($order_type, $order_id, $reg_fee, $patient_info['PATIENTID'], $patient_info['NAME']); + $pay_data = $this->applyPayment($order_type, $order_id, $reg_fee, $patient_info['patientNumber'], $patient_info['name']); // 去除无用数据 unset($pay_data['merchantId'], $pay_data['merchantName'], $pay_data['channelId'], $pay_data['channelName']); @@ -94,12 +94,13 @@ class RegisterLogic throw new GeneralException('找不到患者信息,请重新再试!', Response::HTTP_BAD_REQUEST); } - $patient_info = $this->his_client->getPatientInfo($info['patient_id'], CardType::OUTPATIENT_NO, $info['name']); - if (!isset($patient_info['RESULTCODE']) || $patient_info['RESULTCODE'] !== '0') { - throw new GeneralException($patient_info['ERRORMSG'] ?? '找不到患者信息,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); + $response = $this->his_client->getPatientInfo($info['patient_id'], CardType::OUTPATIENT_NO, $info['name']); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '找不到患者信息,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } // 添加Patient 表ID + $patient_info = &$response['response']; $patient_info['id'] = $info['id']; $this->info('挂号患者信息', $patient_info); @@ -194,6 +195,7 @@ class RegisterLogic ]; $order = $this->order_model->createOrder( + $patient_info['id'], $order_id, $pay_type, $reg_fee * 100, diff --git a/app/Http/Logics/Registration/ScheduleLogic.php b/app/Http/Logics/Registration/ScheduleLogic.php index 1181ff3..b4a0ced 100644 --- a/app/Http/Logics/Registration/ScheduleLogic.php +++ b/app/Http/Logics/Registration/ScheduleLogic.php @@ -32,8 +32,8 @@ class ScheduleLogic { $response = $this->his_client->getDepType('', '','01', $date); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { - throw new GeneralException($response['ERRORMSG'] ?? '暂无科室排班!', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '暂无科室排班!', Response::HTTP_SERVICE_UNAVAILABLE); } return $response; @@ -51,8 +51,8 @@ class ScheduleLogic $type = $date === date('Y-m-d') ? '3' : '1'; $response = $this->his_client->getDoctorLists($dept_id, $type, '', $date); - if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { - throw new GeneralException($response['ERRORMSG'] ?? '该科室暂无医生排班!', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($response['success']) || !$response['success']) { + throw new GeneralException($response['msg'] ?? '该科室暂无医生排班!', Response::HTTP_SERVICE_UNAVAILABLE); } return $response; diff --git a/app/Http/Resources/Patient/PatientDetailsResource.php b/app/Http/Resources/Patient/PatientDetailsResource.php index 15d89c5..555f716 100644 --- a/app/Http/Resources/Patient/PatientDetailsResource.php +++ b/app/Http/Resources/Patient/PatientDetailsResource.php @@ -16,10 +16,10 @@ class PatientDetailsResource extends JsonResource { return [ 'patient_id' => $this->resource['patient_id'], - 'patient_card_id' => $this->resource['patient_card_id'], 'patient_name' => $this->resource['name'], - 'card_no' => $this->resource['card_no'], + // 'card_no' => $this->resource['card_no'], 'sex' => $this->resource['sex'], + 'birthday' => $this->resource['birthday'], 'is_default' => $this->resource['def_status'] ]; } diff --git a/app/Http/Resources/Registration/Schedule/DeptListsResource.php b/app/Http/Resources/Registration/Schedule/DeptListsResource.php index c6912c1..489789b 100644 --- a/app/Http/Resources/Registration/Schedule/DeptListsResource.php +++ b/app/Http/Resources/Registration/Schedule/DeptListsResource.php @@ -19,9 +19,9 @@ class DeptListsResource extends JsonResource $lists = []; foreach ($this->resource['ITEM'] as $v) { $lists[] = [ - 'dept_id' => $v['DEPID'], - 'dept_name' => $v['DEPNAME'], - 'dept_intro' => $v['INTRODUCE'] + 'dept_id' => $v['typeId'], + 'dept_name' => $v['typeName'], + // 'dept_intro' => $v['INTRODUCE'] ]; } diff --git a/app/Jobs/Message/Message.php b/app/Jobs/Message/Message.php new file mode 100644 index 0000000..9b64a79 --- /dev/null +++ b/app/Jobs/Message/Message.php @@ -0,0 +1,48 @@ +getApp()->getClient()->postJson($type->api()->value, $message); + + Log::channel('SendWeChatMessage')->info('Push WeChat Message', [$type->label(), $message, $response->getContent(false)]); + + return $response; + } +} diff --git a/app/Jobs/Message/SubscriptionMessage.php b/app/Jobs/Message/SubscriptionMessage.php new file mode 100644 index 0000000..0e95de6 --- /dev/null +++ b/app/Jobs/Message/SubscriptionMessage.php @@ -0,0 +1,20 @@ +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(); + } +} diff --git a/app/Models/Order.php b/app/Models/Order.php index 5e7642c..6c86342 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -79,7 +79,7 @@ class Order extends Model */ public function patient(): belongsTo { - return $this->belongsTo(Patient::class, 'patient_id', 'patient_id'); + return $this->belongsTo(Patient::class, 'id', 'relate_patient_id'); } /** @@ -162,6 +162,7 @@ class Order extends Model /** * 创建订单 + * @param int $relate_patient_id * @param string $order_id * @param PayType $pay_type * @param float $fee @@ -174,11 +175,12 @@ class Order extends Model * @param array $record_info * @return mixed */ - public function createOrder(string $order_id, PayType $pay_type, float $fee, float $reduce_fee, string $open_id, string $patient_id, string $patient_name, Type $order_type, SourceId $source_id, array $record_info = []): mixed + public function createOrder(int $relate_patient_id, string $order_id, PayType $pay_type, float $fee, float $reduce_fee, string $open_id, string $patient_id, string $patient_name, Type $order_type, SourceId $source_id, array $record_info = []): mixed { $order_info = [ 'relate_id' => 0, + 'relate_patient_id' => $relate_patient_id, 'order_id' => $order_id, 'his_order_id' => '', 'transaction_id' => '', @@ -228,6 +230,7 @@ class Order extends Model /** * 创建退费/冲正订单 * @param int $relate_order_id + * @param int $relate_patient_id * @param string $order_id * @param PayType $pay_type * @param float $fee @@ -238,10 +241,11 @@ class Order extends Model * @param SourceId $source_id * @return mixed */ - public function createRefundOReverseOrder(int $relate_order_id, string $order_id, PayType $pay_type, float $fee, string $open_id, string $patient_id, string $patient_name, Type $order_type, SourceId $source_id): mixed + public function createRefundOReverseOrder(int $relate_order_id, int $relate_patient_id, string $order_id, PayType $pay_type, float $fee, string $open_id, string $patient_id, string $patient_name, Type $order_type, SourceId $source_id): mixed { $order_info = [ 'relate_id' => $relate_order_id, + 'relate_patient_id' => $relate_patient_id, 'order_id' => $order_id, 'his_order_id' => '', 'transaction_id' => '', diff --git a/app/Models/RegistrationRecord.php b/app/Models/RegistrationRecord.php index 0f2468c..a2c24c9 100644 --- a/app/Models/RegistrationRecord.php +++ b/app/Models/RegistrationRecord.php @@ -32,6 +32,7 @@ class RegistrationRecord extends Model 'lock_status', 'lock_at', 'extra_info', + 'reminder_sent' ]; /** @@ -45,6 +46,7 @@ class RegistrationRecord extends Model 'relate_patient_id' => 'integer', 'lock_status' => 'integer', 'lock_at' => 'datetime', + 'reminder_sent' => 'integer' ]; /** diff --git a/app/Models/PushWechatMessage.php b/app/Models/SendMessageJob.php similarity index 68% rename from app/Models/PushWechatMessage.php rename to app/Models/SendMessageJob.php index 7ae8d52..b39e6b4 100644 --- a/app/Models/PushWechatMessage.php +++ b/app/Models/SendMessageJob.php @@ -4,19 +4,13 @@ declare(strict_types=1); namespace App\Models; -use App\Dictionary\PushMessage\Type; -use App\Dictionary\WeChat\Official\SubscribeId; -use App\Dictionary\WeChat\Official\TemplateId; -use App\Jobs\SendWeChatMessage; +use App\Dictionary\SendMessage\Type; +use App\Dictionary\WeChat\MiniProgram\SubscribeId; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use Modules\Official\Structs\Message\CustomMessage; -use Modules\Official\Structs\Message\SubscribeMessage; -use Modules\Official\Structs\Message\TemplateData\Common; -use Modules\Official\Structs\Message\TemplateMessage; -class PushWechatMessage extends Model +class SendMessageJob extends Model { use HasFactory; @@ -34,6 +28,7 @@ class PushWechatMessage extends Model 'content', 'number', 'status', + 'fail_reason', 'sent_at', ]; @@ -71,19 +66,21 @@ class PushWechatMessage extends Model * 插入推送消息队列 * @param int $relate_order_id * @param int $relate_patient_id - * @param TemplateId|SubscribeId|null $template_id - * @param TemplateMessage|SubscribeMessage|CustomMessage $message + * @param Type $type + * @param SubscribeId|null $template_id + * @param array $message + * @param string $scene * @return mixed */ - public function insertMessageJobs(int $relate_order_id, int $relate_patient_id, TemplateId|SubscribeId|null $template_id, TemplateMessage|SubscribeMessage|CustomMessage $message): mixed + public function insertMessageJobs(int $relate_order_id, int $relate_patient_id, Type $type, SubscribeId|null $template_id, array $message, string $scene = ''): mixed { $data = [ 'relate_order_id' => $relate_order_id, 'relate_patient_id' => $relate_patient_id, - 'type' => Type::OFFICIAL_TEMPLATE->value, + 'type' => $type->value, 'template_id' => $template_id, 'scene' => '', - 'content' => serialize($message), + 'content' => json_encode($message, JSON_UNESCAPED_UNICODE), ]; return $this->create($data); diff --git a/app/Services/HisHttp/Client.php b/app/Services/HisHttp/Client.php index dfe1d5c..5bbfe00 100644 --- a/app/Services/HisHttp/Client.php +++ b/app/Services/HisHttp/Client.php @@ -35,7 +35,7 @@ class Client */ protected function commonRequestData(): array { - return [ + /*return [ 'mock' => 0, 'appKey' => '', 'atmName' => '', @@ -44,7 +44,8 @@ class Client 'f1' => '', 'f2' => '', 'f3' => '' - ]; + ];*/ + return []; } /** diff --git a/app/Utils/Traits/SendSubscribeMessage.php b/app/Utils/Traits/SendSubscribeMessage.php new file mode 100644 index 0000000..ec944d2 --- /dev/null +++ b/app/Utils/Traits/SendSubscribeMessage.php @@ -0,0 +1,260 @@ + $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); + } +} diff --git a/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php b/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php index aaf3748..d98b068 100644 --- a/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php +++ b/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php @@ -72,9 +72,8 @@ class ClientMockHttpTransfer extends HttpTransferAbstract public function responseFormat(mixed $data): mixed { try { - // 此处为xml格式 - $obj = simplexml_load_string((string)$data, 'SimpleXMLElement', LIBXML_NOCDATA); - return json_decode((string)json_encode($obj), true); + // 此处为json格式 + return json_decode((string)$data, true); } catch (Exception $e) { throw new Exception($e->getMessage()); } @@ -98,7 +97,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract */ private function mockRegisterCard(array $params): self { - $this->transfer_response = '0建卡成功'; + $this->transfer_response = '{"status":200,"success":true,"msg":"成功","msgDev":null,"response":{"patientId":"2235711"}}'; return $this; } @@ -110,7 +109,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract */ private function mockGetPatientInfo(array $params): self { - $this->transfer_response = '01104468452323193712153735唐超积11937-12-150123299811204468'; + $this->transfer_response = '{"status":200,"success":true,"msg":"成功","msgDev":null,"response":{"patientId":"2235574","cardNo":"230403199903245493","name":"谭玉山","sex":"0","birthday":"1999-03-24","cardStatus":"0","naturePatients":"123","patientNumber":"288712335574"}}'; return $this; } @@ -122,7 +121,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract */ private function mockGetDepLists(array $params): self { - $this->transfer_response = '0Success1234567890内科50.00001531内科专注于诊治呼吸、消化、心血管等系统疾病。5201010152522345678901外科60.00002842外科提供专业的手术治疗服务,包括创伤、整形及器官移植。6301512203033456789012儿科40.00003621儿科为0-18岁儿童提供专业的诊疗与健康管理服务。42588101844567890123皮肤科30.00004411皮肤科诊治常见皮肤病、性病及皮肤美容问题。315765111'; + $this->transfer_response = '{"status":200,"success":true,"msg":"成功","msgDev":null,"response":[{"typeId":"17","typeName":"泌尿外科"},{"typeId":"20","typeName":"体检办证"},{"typeId":"31","typeName":"内分泌科"},{"typeId":"01","typeName":"内科"},{"typeId":"05","typeName":"口腔科"},{"typeId":"19","typeName":"消化内科"},{"typeId":"29","typeName":"呼吸内科门诊"},{"typeId":"33","typeName":"中医减重门诊"},{"typeId":"03","typeName":"中医康复"},{"typeId":"18","typeName":"产前门诊"},{"typeId":"04","typeName":"五官科"},{"typeId":"10","typeName":"妇产科"},{"typeId":"16","typeName":"全科医生门诊"},{"typeId":"28","typeName":"儿童青少年心理门诊"},{"typeId":"02","typeName":"普外科"},{"typeId":"25","typeName":"儿科"},{"typeId":"27","typeName":"精神心理科"},{"typeId":"07","typeName":"急诊内科"},{"typeId":"09","typeName":"皮肤科"},{"typeId":"14","typeName":"急诊外科"},{"typeId":"15","typeName":"骨科"},{"typeId":"26","typeName":"治未病科"},{"typeId":"06","typeName":"专家门诊"},{"typeId":"11","typeName":"妇保门诊"},{"typeId":"12","typeName":"儿保门诊"},{"typeId":"32","typeName":"血液透析门诊"},{"typeId":"08","typeName":"天灸门诊"},{"typeId":"24","typeName":"神经内科"},{"typeId":"30","typeName":"助产士门诊"}]}'; return $this; } @@ -239,7 +238,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract */ private function mockGetDictionaryLists(array $params): self { - $this->transfer_response = '01手术费2治疗费3中药费4西药费5检查费6诊查费7护理费'; + $this->transfer_response = '{"status":200,"success":true,"msg":"成功","msgDev":null,"response":[{"typeId":"4","typeName":"草药费"},{"typeId":"20","typeName":"防疫药品"},{"typeId":"2","typeName":"西药费"},{"typeId":"3","typeName":"中成药"},{"typeId":"22","typeName":"B超"},{"typeId":"25","typeName":"CT检查"},{"typeId":"19","typeName":"X光费"},{"typeId":"1","typeName":"床位费"},{"typeId":"27","typeName":"高值耗材"},{"typeId":"12","typeName":"挂号费"},{"typeId":"11","typeName":"护理费"},{"typeId":"17","typeName":"急诊留观床位费"},{"typeId":"5","typeName":"检查费"},{"typeId":"9","typeName":"检验费"},{"typeId":"15","typeName":"救护车"},{"typeId":"26","typeName":"内镜检查"},{"typeId":"10","typeName":"其它"},{"typeId":"8","typeName":"手术费"},{"typeId":"13","typeName":"输血费"},{"typeId":"14","typeName":"输氧费"},{"typeId":"23","typeName":"碎石"},{"typeId":"21","typeName":"心电图"},{"typeId":"24","typeName":"一般诊疗费"},{"typeId":"16","typeName":"医材费"},{"typeId":"7","typeName":"诊查费"},{"typeId":"6","typeName":"治疗费"},{"typeId":"18","typeName":"自负床位费"}]}'; return $this; } diff --git a/bootstrap/app.php b/bootstrap/app.php index f3ce33c..3bab3e5 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,5 +1,6 @@ create(); + })->withCommands([ + SendAppointmentReminders::class, + ]) + ->create(); diff --git a/config/custom.php b/config/custom.php index 7bf82d9..7980765 100644 --- a/config/custom.php +++ b/config/custom.php @@ -6,5 +6,7 @@ return [ // 绑定就诊卡数上限 - 'max_bind_patient_count' => 5 + 'max_bind_patient_count' => 5, + // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 + 'mini_program_message_state' => 'developer' ]; diff --git a/config/logging.php b/config/logging.php index 0095816..f4784ca 100644 --- a/config/logging.php +++ b/config/logging.php @@ -200,6 +200,15 @@ return [ 'level' => Level::Info, 'max_files' => 0, ], + + // 发送微信消息 + 'send_wechat_message' => [ + 'driver' => 'custom', + 'via' => GeneralDailyLogger::class, + 'service_type' => 'SendWeChatMessage', + 'level' => Level::Info, + 'max_files' => 0, + ] ], ]; diff --git a/config/wechat.php b/config/wechat.php index f18865c..7f07c4e 100644 --- a/config/wechat.php +++ b/config/wechat.php @@ -70,8 +70,8 @@ return [ | 详见:https://easywechat.com/6.x/mini-app/index.html | */ - 'app_id' => env('WECHAT_MINI_APP_ID', 'wxccd0c4f642673a6d'), - 'secret' => env('WECHAT_MINI_APP_SECRET', '73f66753cf45336186f8640b6673d5fb'), + 'app_id' => env('WECHAT_MINI_APP_ID', 'wx84863fc5fadc3f8c'), + 'secret' => env('WECHAT_MINI_APP_SECRET', 'feff14552b5507329e45bd14eec1de72'), 'token' => env('WECHAT_MINI_TOKEN', ''), 'aes_key' => env('WECHAT_MINI_AES_KEY', ''), diff --git a/database/migrations/2023_03_03_080312_create_orders_table.php b/database/migrations/2023_03_03_080312_create_orders_table.php index 68f2e76..4cf92b5 100644 --- a/database/migrations/2023_03_03_080312_create_orders_table.php +++ b/database/migrations/2023_03_03_080312_create_orders_table.php @@ -13,7 +13,8 @@ return new class () extends Migration { { Schema::create('orders', static function (Blueprint $table) { $table->id(); - $table->integer('relate_id')->default(0)->comment('关联订单号'); + $table->integer('relate_id')->default(0)->comment('关联订单表ID'); + $table->integer('relate_patient_id')->default(0)->comment('关联患者表ID'); $table->string('order_id', 64)->unique()->comment('订单ID'); $table->string('his_order_id', 64)->comment('his订单ID'); $table->string('transaction_id', 64)->comment('交易平台单号'); diff --git a/database/migrations/2023_03_03_080715_create_registration_records_table.php b/database/migrations/2023_03_03_080715_create_registration_records_table.php index a5965cb..2d6adf3 100644 --- a/database/migrations/2023_03_03_080715_create_registration_records_table.php +++ b/database/migrations/2023_03_03_080715_create_registration_records_table.php @@ -28,6 +28,7 @@ return new class () extends Migration { $table->timestamp('lock_at')->nullable()->comment('锁号时间'); $table->timestamp('unlock_at')->nullable()->comment('解锁时间'); $table->text('extra_info')->comment('额外的挂号信息'); + $table->tinyInteger('reminder_sent')->default(0)->comment('是否已推送就诊提醒'); $table->timestamps(); $table->engine = 'InnoDB'; }); diff --git a/database/migrations/2023_03_03_082229_create_push_wechat_messages_table.php b/database/migrations/2023_03_03_082229_create_send_message_jobs_table.php similarity index 81% rename from database/migrations/2023_03_03_082229_create_push_wechat_messages_table.php rename to database/migrations/2023_03_03_082229_create_send_message_jobs_table.php index a96c222..eaf5459 100644 --- a/database/migrations/2023_03_03_082229_create_push_wechat_messages_table.php +++ b/database/migrations/2023_03_03_082229_create_send_message_jobs_table.php @@ -11,17 +11,18 @@ return new class () extends Migration { */ public function up(): void { - Schema::create('push_wechat_messages', static function (Blueprint $table) { + Schema::create('send_message_jobs', static function (Blueprint $table) { $table->id(); $table->integer('relate_order_id')->default(0)->index()->comment('关联订单表ID'); $table->integer('relate_patient_id')->index()->comment('关联患者表ID'); - $table->tinyInteger('type')->index()->comment('消息类型 1公众号模板消息 2公众号订阅消息 3公众号一次性订阅消息 4公众号客服消息'); + $table->tinyInteger('type')->index()->comment('消息类型 消息类型 1模板消息 2长期订阅消息 3一次性订阅消息 4客服消息'); $table->string('template_id', 64)->comment('推送消息ID'); $table->string('scene', 32)->default('')->comment('订阅场景'); $table->text('content')->comment('序列化推送消息内容'); $table->unsignedTinyInteger('number')->default(0)->index()->comment('已尝试发送次数'); $table->unsignedTinyInteger('status')->default(0)->index()->comment('状态 0尚未推送 1已推送 2推送异常'); $table->string('msg_id', 32)->default('')->comment('推送后返回的msg_id'); + $table->string('fail_reason')->default('')->comment('失败原因'); $table->timestamp('sent_at')->nullable()->comment('推送时间'); $table->timestamps(); $table->engine = 'InnoDB'; @@ -33,6 +34,6 @@ return new class () extends Migration { */ public function down(): void { - Schema::dropIfExists('push_wechat_messages'); + Schema::dropIfExists('send_message_jobs'); } }; diff --git a/database/migrations/2024_12_24_110504_create_personal_access_tokens_table.php b/database/migrations/2024_12_24_110504_create_personal_access_tokens_table.php deleted file mode 100644 index e828ad8..0000000 --- a/database/migrations/2024_12_24_110504_create_personal_access_tokens_table.php +++ /dev/null @@ -1,33 +0,0 @@ -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'); - } -};