香洲二院小程序
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.
 
 
 
mini_xzey/app/Http/Logics/Patient/PatientLogic.php

309 lines
11 KiB

<?php
declare(strict_types = 1);
namespace App\Http\Logics\Patient;
use App\Dictionary\Patient\CardType;
use App\Dictionary\Patient\Sex;
use App\Dictionary\WeChat\MiniProgram\OpenApi;
use App\Exceptions\GeneralException;
use App\Models\Patient;
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 Exception;
use Illuminate\Auth\AuthenticationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
class PatientLogic
{
use Logger;
use MiniProgramAuth;
use UniversalEncryption;
use SendSubscribeMessage;
private Client $his_client;
private Patient $patient_model;
/**
* PatientLogic Construct
* @throws AuthenticationException
*/
public function __construct()
{
$this->authInitialize();
$this->patient_model = new Patient();
$this->his_client = app('HisHttpService');
}
/**
* 获取绑定患者列表
*/
public function getAllPatientLists()
{
return $this->patient_model->getBindPatientLists($this->open_id);
}
/**
* 卡详情
* @param string $patient_number
* @return Patient
* @throws GeneralException
*/
public function getPatientDetails(string $patient_number): Patient
{
$info = $this->patient_model->getBindPatientInfoByPatientNumber($this->open_id, $patient_number);
if(empty($info)) {
throw new GeneralException('找不到该就诊卡!');
}
// 获取患者信息
$response = $this->his_client->getPatientInfo($info['patient_number'], CardType::OUTPATIENT_NO, $info['name']);
if (!isset($response['success']) || !$response['success']) {
throw new GeneralException($response['msg'] ?? '找不到该就诊卡!', Response::HTTP_SERVICE_UNAVAILABLE);
}
$info->birthday = $response['response']['birthday'] ?? '';
return $info;
}
/**
* 建档
* @param array $data
* @return string
* @throws GeneralException
*/
public function createPatient(array $data): string
{
// 简单判断一下证件类型
$card_type = getIDCardType($data['card_no']);
switch ($card_type) {
// 身份证
case 1:
$sex = getGenderByIdCard($data['card_no']) === 1 ? Sex::MALE : Sex::WOMEN;
$birthday = getBirthdayByIdCard($data['card_no']);
break;
// 2017 / 2023 外国人永居证
case 3:
case 4:
if ($card_type == 3) {
$sex = Sex::from((int)$data['sex']);
$birthday = getBirthdayBy2017ForeignersIDCard($data['card_no']);
} else {
$sex = getGenderByIdCard($data['card_no']) === 1 ? Sex::MALE : Sex::WOMEN;
$birthday = getBirthdayByIdCard($data['card_no']);
}
break;
default:
$sex = Sex::from((int)$data['sex']);
$birthday = &$data['birthday'];
break;
}
//过滤名字特殊字符
$data['name'] = replaceSpecialChar($data['name']);
$card_type = CardType::from((int)$data['card_type']);
// 查询绑定超过X个
$bind_count = $this->patient_model->getBindPatientCount($this->open_id);
if ($bind_count >= config('custom.max_bind_patient_count')) {
throw new GeneralException('该微信达到绑定卡上限!');
}
// 查询患者信息
$response = $this->his_client->getPatientInfo($data['card_no'], $card_type, $data['name']);
$this->info('查询患者信息:', $response);
if (!isset($response['success']) || !$response['success']) {
$patient_id = &$response['response']['patientNumber'];
// 查询是否已绑定
$result = $this->patient_model->getPatientInfoByPatientId($patient_id);
if ($result && $result['open_id'] == $this->open_id) {
throw new GeneralException('您已绑定该就诊卡号!');
}
if ($result && $result['open_id'] != $this->open_id) {
throw new GeneralException('该卡号已被其他微信用户绑定!');
}
} else {
// 查询失败,走建档
$response = $this->his_client->registerCard(
$data['card_no'],
$card_type,
$data['name'],
$sex,
$birthday,
$data['card_no'],
$data['phone'],
$data['address']
);
$this->info('建档患者:'. $data['name']. '建档结果', $response);
if (!isset($response['success']) || !$response['success']) {
throw new GeneralException('建档失败,失败原因:'. $response['msg'] ?? '未知错误', Response::HTTP_SERVICE_UNAVAILABLE);
}
}
// 再查一遍接口 获取患者信息
$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']['patientId'];
$patient_number = $response['response']['patientNumber'];
// 写入数据库
$result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_id, $patient_number, $data['name'], $sex);
if (!$result) {
throw new GeneralException('数据保存失败,请重试!', Response::HTTP_INTERNAL_SERVER_ERROR);
}
$this->sendBindPatientSubscribeMessage($this->open_id, $result->id, $data['name']);
return $patient_id;
}
/**
* 绑定患者
* @param array $data
* @return string
* @throws GeneralException
*/
public function bindPatient(array $data): string
{
//过滤名字特殊字符
$data['name'] = replaceSpecialChar($data['name']);
$card_type = CardType::from((int)$data['card_type']);
// 查询超过X个
$bind_count = $this->patient_model->getBindPatientCount($this->open_id);
if ($bind_count >= config('custom.max_bind_patient_count')) {
throw new GeneralException('该微信达到绑定卡上限!');
}
// 查询患者信息
$response = $this->his_client->getPatientInfo($data['card_no'], $card_type, $data['name']);
$this->info('查询患者信息:', $response);
if (!isset($response['success']) || !$response['success']) {
throw new GeneralException($response['msg'] ?? '未知错误');
}
$patient_info = &$response['response'];
$patient_id = &$patient_info['patientId'];
$patient_number = &$patient_info['patientNumber'];
$sex = Sex::from((int) $patient_info['sex']);
if ($patient_info['patientNumber'] != $data['patient_id']) {
throw new GeneralException('该证件号已建档,但就诊卡号不匹配!');
}
if ($patient_info['name'] != $data['name']) {
throw new GeneralException('该证件号已建档,但姓名不匹配!');
}
if ($patient_info['cardNo'] != $data['card_no']) {
throw new GeneralException('该就诊号已建档,但证件号码不匹配!');
}
// 查询是否已绑定
$result = $this->patient_model->getPatientInfoByPatientId($data['patient_id']);
if ($result && $result['openid'] == $this->open_id) {
throw new GeneralException('您已绑定该就诊卡号!');
}
if ($result && $result['openid'] != $this->open_id) {
throw new GeneralException('该卡号已被其他微信用户绑定!');
}
// 写入数据库
$result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_id, $patient_number, $data['name'], $sex);
if (!$result) {
throw new GeneralException('数据保存失败,请重试!', Response::HTTP_INTERNAL_SERVER_ERROR);
}
$this->sendBindPatientSubscribeMessage($this->open_id, $result->id, $data['name']);
return $patient_number;
}
/**
* 设置默认就诊卡
* @param string $patient_number
* @return bool
* @throws GeneralException
*/
public function setDefaultPatient(string $patient_number): bool
{
$info = $this->patient_model->getBindPatientInfoByPatientNumber($this->open_id, $patient_number);
if (empty($info)) {
throw new GeneralException('该就诊卡不存在!');
}
$result = $this->patient_model->setDefaultPatient($this->open_id, $info->patient_id);
if (!$result) {
throw new GeneralException('设置失败,请稍后再试!', Response::HTTP_INTERNAL_SERVER_ERROR);
}
return true;
}
/**
* 解绑
* @param string $patient_number
* @return bool
* @throws GeneralException
*/
public function cancelBindPatient(string $patient_number): bool
{
$info = $this->patient_model->getBindPatientInfoByPatientNumber($this->open_id, $patient_number);
if (empty($info)) {
throw new GeneralException('该就诊卡不存在!');
}
$result = $this->patient_model->deletePatient($this->open_id, $info->patient_id);
if (!$result) {
throw new GeneralException('解绑失败,请稍后再试!', Response::HTTP_INTERNAL_SERVER_ERROR);
}
$this->sendUnbindPatientSubscribeMessage($this->open_id, $info->id, $info['name'], ' ', $patient_number);
return true;
}
/**
* 获取患者手机号码
* @param string $code
* @return array
* @throws GeneralException
*/
public function getPhoneNumber(string $code): array
{
try {
$mini = getWeChatMiniProgramApp();
$response = $mini->getClient()->postJson(OpenApi::GET_PHONE_NUMBER->value, [
'code' => $code
]);
$this->info('获取手机号码接口返回', [$response]);
if ($response['errcode'] !== 0 || empty($response['phone_info'])) {
throw new GeneralException('获取手机号码失败,请稍后再试!');
}
return $response['phone_info'];
} catch (ExceptionInterface|Exception $e) {
//service error
$message = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
$this->error('获取手机号码接口报错', [$message]);
throw new GeneralException('获取手机号码失败,请稍后再试!', Response::HTTP_BAD_REQUEST);
}
}
}