parent
4518acb3a8
commit
03e6e10048
@ -0,0 +1,68 @@ |
||||
<?php |
||||
declare(strict_types = 1); |
||||
|
||||
namespace App\Http\Controllers\Report; |
||||
|
||||
use App\Exceptions\GeneralException; |
||||
use App\Http\Logics\Registration\RecordLogic; |
||||
use App\Http\Logics\Report\InspectLogic; |
||||
use App\Http\Resources\Report\Inspect\DetailsResource; |
||||
use App\Http\Resources\Report\Inspect\ListsResource; |
||||
use Illuminate\Http\JsonResponse; |
||||
use Illuminate\Http\Request; |
||||
use Symfony\Component\HttpFoundation\Response; |
||||
|
||||
class InspectController |
||||
{ |
||||
protected InspectLogic $inspect_logic; |
||||
|
||||
/** |
||||
* InspectController Construct. |
||||
*/ |
||||
public function __construct() |
||||
{ |
||||
$this->inspect_logic = new InspectLogic(); |
||||
} |
||||
|
||||
/** |
||||
* 获取检查报告列表 |
||||
* @param Request $request |
||||
* @param string $patient_id |
||||
* @return JsonResponse |
||||
* @throws GeneralException |
||||
*/ |
||||
public function lists(Request $request, string $patient_id): JsonResponse |
||||
{ |
||||
$validated = $request->validate([ |
||||
'start_date' => 'required|date_format:Y-m-d', |
||||
'end_date' => 'required|date_format:Y-m-d|after:start_date', |
||||
], [ |
||||
'start_date.required' => '请选择查询开始日期', |
||||
'end_date.required' => '请选择查询结束日期', |
||||
'start_date.date_format' => '日期格式错误', |
||||
'end_date.date_format' => '日期格式错误', |
||||
'end_date.after' => '查询日期错误', |
||||
]); |
||||
|
||||
// 日期必须在3个月之内 |
||||
|
||||
$response = $this->inspect_logic->lists($patient_id, $validated['start_date'], $validated['end_date']); |
||||
|
||||
return jsonResponse(Response::HTTP_OK, 'success', ListsResource::make($response)->toArray()); |
||||
} |
||||
|
||||
/** |
||||
* 获取缴费记录详情 |
||||
* @param Request $request |
||||
* @param string $patient_id |
||||
* @param string $serial_no |
||||
* @return JsonResponse |
||||
* @throws GeneralException |
||||
*/ |
||||
public function details(Request $request, string $patient_id, string $serial_no): JsonResponse |
||||
{ |
||||
$response = $this->inspect_logic->details($patient_id, $serial_no); |
||||
|
||||
return jsonResponse(Response::HTTP_OK, 'success.', DetailsResource::make($response)->toArray()); |
||||
} |
||||
} |
@ -0,0 +1,143 @@ |
||||
<?php |
||||
declare(strict_types = 1); |
||||
|
||||
namespace App\Http\Logics\Report; |
||||
|
||||
use App\Dictionary\Order\PayType; |
||||
use App\Dictionary\Order\SourceId; |
||||
use App\Dictionary\Order\Status; |
||||
use App\Dictionary\Order\Type; |
||||
use App\Dictionary\Patient\CardType; |
||||
use App\Exceptions\GeneralException; |
||||
use App\Models\Order; |
||||
use App\Models\Patient; |
||||
use App\Models\RegistrationRecord; |
||||
use App\Services\HisHttp\Client; |
||||
use App\Utils\Traits\BuildCacheKeyName; |
||||
use App\Utils\Traits\Logger; |
||||
use App\Utils\Traits\MiniProgramAuth; |
||||
use App\Utils\Traits\SendSubscribeMessage; |
||||
use Illuminate\Auth\AuthenticationException; |
||||
use Illuminate\Support\Facades\Cache; |
||||
use Illuminate\Support\Facades\Redis; |
||||
use ReflectionException; |
||||
use Symfony\Component\HttpFoundation\Response; |
||||
use UnifyPayment\Cores\Struct\RefundOrder; |
||||
use UnifyPayment\Unify; |
||||
|
||||
class InspectLogic |
||||
{ |
||||
use Logger; |
||||
use MiniProgramAuth; |
||||
use BuildCacheKeyName; |
||||
|
||||
private Client $his_client; |
||||
|
||||
private Patient $patient_model; |
||||
|
||||
private Order $order_model; |
||||
|
||||
/** |
||||
* RecordLogic Construct |
||||
* @throws AuthenticationException |
||||
*/ |
||||
public function __construct() |
||||
{ |
||||
$this->authInitialize(); |
||||
$this->setChannel('refund'); |
||||
$this->his_client = app('HisHttpService'); |
||||
$this->patient_model = new Patient(); |
||||
} |
||||
|
||||
/** |
||||
* 获取报告列表 |
||||
* @param string $patient_number |
||||
* @param string $start_date |
||||
* @param string $end_date |
||||
* @return mixed |
||||
* @throws GeneralException |
||||
*/ |
||||
public function lists(string $patient_number, string $start_date, string $end_date): mixed |
||||
{ |
||||
$patient_info = $this->getHisPatientInfo($this->open_id, $patient_number); |
||||
|
||||
$response = $this->his_client->getInspectReportLists($patient_info['name'], $patient_info['idCardNo'], $start_date, $end_date); |
||||
|
||||
if (!isset($response['success']) || !$response['success']) { |
||||
throw new GeneralException($response['msg'] ?? '找不到该就诊卡!', Response::HTTP_SERVICE_UNAVAILABLE); |
||||
} |
||||
|
||||
Redis::setex($this->getInspectReportListsKey($this->open_id, $patient_info['patient_id']), 3600, json_encode($response['data'], JSON_UNESCAPED_UNICODE)); |
||||
return $response['data']; |
||||
} |
||||
|
||||
/** |
||||
* 获取报告详情 |
||||
* @param string $patient_number |
||||
* @param string $serial_no |
||||
* @return array |
||||
* @throws GeneralException |
||||
*/ |
||||
public function details(string $patient_number, string $serial_no) |
||||
{ |
||||
$patient_info = $this->getPatientInfo($this->open_id, $patient_number); |
||||
|
||||
$report_lists_cache_key = $this->getInspectReportListsKey($this->open_id, $patient_info['patient_id']); |
||||
if (!Redis::exists($report_lists_cache_key)) { |
||||
throw new GeneralException('找不到报告详情,请重新再试!', Response::HTTP_BAD_REQUEST); |
||||
} |
||||
|
||||
$lists = Redis::get($report_lists_cache_key); |
||||
$lists = json_decode($lists, true); |
||||
|
||||
$info = []; |
||||
foreach ($lists as $k => $v) { |
||||
if ($serial_no === $v['sourceId']) { |
||||
$info = []; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (empty($info)) { |
||||
throw new GeneralException('找不到报告详情,请重新再试!', Response::HTTP_BAD_REQUEST); |
||||
} |
||||
|
||||
return $info; |
||||
} |
||||
|
||||
/** |
||||
* 获取数据库里的患者信息 |
||||
* @param string $open_id |
||||
* @param string $patient_number |
||||
* @return mixed |
||||
* @throws GeneralException |
||||
*/ |
||||
protected function getPatientInfo(string $open_id, string $patient_number): mixed |
||||
{ |
||||
$info = $this->patient_model->getBindPatientInfoByPatientNumber($open_id, $patient_number); |
||||
if (empty($info)) { |
||||
throw new GeneralException('找不到患者信息,请重新再试!', Response::HTTP_BAD_REQUEST); |
||||
} |
||||
|
||||
return $info; |
||||
} |
||||
|
||||
/** |
||||
* 获取HIS里的患者信息 |
||||
* @param string $open_id |
||||
* @param string $patient_number |
||||
* @return mixed |
||||
* @throws GeneralException |
||||
*/ |
||||
protected function getHisPatientInfo(string $open_id, string $patient_number): mixed |
||||
{ |
||||
$info = $this->getPatientInfo($open_id, $patient_number); |
||||
|
||||
$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); |
||||
} |
||||
|
||||
return $response['data']; |
||||
} |
||||
} |
@ -0,0 +1,72 @@ |
||||
<?php |
||||
|
||||
namespace App\Http\Resources\Report\Inspect; |
||||
|
||||
use Illuminate\Http\Request; |
||||
use Illuminate\Http\Resources\Json\JsonResource; |
||||
|
||||
class DetailsResource extends JsonResource |
||||
{ |
||||
/** |
||||
* Transform the resource into an array. |
||||
* |
||||
* @return array<string, mixed> |
||||
*/ |
||||
public function toArray(Request $request = null): array |
||||
{ |
||||
if (empty($this->resource)) { |
||||
return []; |
||||
} |
||||
|
||||
$lists = []; |
||||
foreach ($this->resource['response']['body'] as $k => $v) { |
||||
// 过滤掉诊断为接口调用正常的第一条数据 |
||||
if ($v['diagnose'] === '医院接口调用正常') { |
||||
continue; |
||||
} |
||||
|
||||
$lists[] = [ |
||||
'clinic_no' => $v['clinicNo'], |
||||
'serial_no' => $v['sourceId'], |
||||
'source_form' => $v['sourceFrom'], |
||||
'dept_id' => $v['dept']['localCode'], |
||||
'dept_name' => $v['dept']['localText'], |
||||
'doctor_id' => $v['doctor']['localText'], |
||||
'doctor_name' => $v['doctor']['localText'], |
||||
'exam_type' => $v['examMethod'], |
||||
'exam_name' => $v['examName'], |
||||
'exam_purpose' => $v['examPurpose'], |
||||
'diagnose' => $v['diagnose'], |
||||
'exam_view' => $v['examView'], |
||||
'diagnose_opinion' =>$v['diagnose_opinion'], |
||||
'created_time' => $v['createDt'], |
||||
'check_time' => $v['checkDt'], |
||||
'report_time' => $v['reportDt'], |
||||
'comment' => $v['comment'], |
||||
// 患者信息 |
||||
'patient_name' => $v['patient']['name'], |
||||
'patient_gender' => $v['patient']['gender'], |
||||
'patient_birth' => $v['patient']['birthday'], |
||||
// 冗余信息 |
||||
'org_id' => $v['org']['localCode'], |
||||
'org_name' => $v['org']['localText'], |
||||
'equipment_name' => $v['equipmentName'], |
||||
'equipment_no' => $v['equipmentNameNo'], |
||||
'report_doctor_id' => $v['rpDoctor']['localCode'], |
||||
'report_doctor_name' => $v['rpDoctor']['localText'], |
||||
'report_org_id' => $v['rpOrg']['localCode'], |
||||
'report_org_name' => $v['rpOrg']['localText'], |
||||
'crisis_flag' => $v['crisisFlag'], |
||||
'crisis_desc' => $v['crisisDesc'], |
||||
'crisis_content' => $v['crisisContent'], |
||||
'unusual_flag' => $v['unusualFlag'], |
||||
'deal_flag' => $v['dealFlag'], |
||||
'need_deal_flag' => $v['needDealFlag'], |
||||
// pacs 图片数组一般为空 |
||||
'pacs_images' => (array) ($v['pacs'] ?? []) |
||||
]; |
||||
} |
||||
|
||||
return $lists; |
||||
} |
||||
} |
@ -0,0 +1,51 @@ |
||||
<?php |
||||
|
||||
namespace App\Http\Resources\Report\Inspect; |
||||
|
||||
use Illuminate\Http\Request; |
||||
use Illuminate\Http\Resources\Json\JsonResource; |
||||
|
||||
class ListsResource extends JsonResource |
||||
{ |
||||
/** |
||||
* Transform the resource into an array. |
||||
* |
||||
* @return array<string, mixed> |
||||
*/ |
||||
public function toArray(Request $request = null): array |
||||
{ |
||||
if (empty($this->resource)) { |
||||
return []; |
||||
} |
||||
|
||||
$lists = []; |
||||
foreach ($this->resource['response']['body'] as $k => $v) { |
||||
// 过滤掉诊断为接口调用正常的第一条数据 |
||||
if ($v['diagnose'] === '医院接口调用正常') { |
||||
continue; |
||||
} |
||||
|
||||
$lists[] = [ |
||||
'clinic_no' => $v['clinicNo'], |
||||
'serial_no' => $v['sourceId'], |
||||
'source_form' => $v['sourceFrom'], |
||||
'dept_id' => $v['dept']['localCode'], |
||||
'dept_name' => $v['dept']['localText'], |
||||
'doctor_id' => $v['doctor']['localText'], |
||||
'doctor_name' => $v['doctor']['localText'], |
||||
'exam_type' => $v['examMethod'], |
||||
'exam_name' => $v['examName'], |
||||
'exam_purpose' => $v['examPurpose'], |
||||
'diagnose' => $v['diagnose'], |
||||
'exam_view' => $v['examView'], |
||||
'diagnose_opinion' =>$v['diagnose_opinion'], |
||||
'created_time' => $v['createDt'], |
||||
'check_time' => $v['checkDt'], |
||||
'report_time' => $v['reportDt'], |
||||
'comment' => $v['comment'], |
||||
]; |
||||
} |
||||
|
||||
return $lists; |
||||
} |
||||
} |
@ -0,0 +1,205 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace App\Services\MedicalAuth; |
||||
|
||||
use App\Utils\Traits\HttpRequest; |
||||
use Exception; |
||||
use GuzzleHttp\Exception\GuzzleException; |
||||
use JsonException; |
||||
use Psr\Http\Message\ResponseInterface; |
||||
// use JetBrains\PhpStorm\ArrayShape; |
||||
|
||||
/** |
||||
* 医保移动支付免密授权 - 微信端 |
||||
* |
||||
* @link https://yb.qq.com/yibao-payment/doc?nodeId=83679977515675648 |
||||
*/ |
||||
class Authorization |
||||
{ |
||||
|
||||
use HttpRequest; |
||||
|
||||
/** |
||||
* 配置数组 |
||||
* @var string[] |
||||
*/ |
||||
/*#[ArrayShape([ |
||||
'app_id' => "string", |
||||
'partner_id' => "string", |
||||
'partner_secret' => "string", |
||||
'channel' => "string", |
||||
'org_chnl_crtf_codg' => "string", |
||||
'org_codg' => "string", |
||||
'org_app_id' => "string", |
||||
'auth_return_url' => "string", |
||||
])]*/ |
||||
private array $config; |
||||
|
||||
/** |
||||
* 城市编码 441721 香洲区 |
||||
* @var string |
||||
*/ |
||||
private string $city_code = '441721'; |
||||
|
||||
/** |
||||
* 授权查询host地址 |
||||
* @var string |
||||
*/ |
||||
private string $host = 'https://test-receiver.wecity.qq.com'; |
||||
// private string $host = 'https://mip-receiver.tengmed.com'; |
||||
|
||||
/** |
||||
* 免密授权host地址 |
||||
* @var string |
||||
*/ |
||||
private string $auth_host = 'https://mitest.wecity.qq.com'; |
||||
// private string $auth_host = 'https://card.wecity.qq.com'; |
||||
|
||||
/** |
||||
* Authorization Class Construct. |
||||
*/ |
||||
public function __construct() |
||||
{ |
||||
$this->config = config('wechat.medical.auth'); |
||||
} |
||||
|
||||
/** |
||||
* 获取签名 |
||||
* @param string $timestamp |
||||
* @return string |
||||
*/ |
||||
private function getSign(string $timestamp): string |
||||
{ |
||||
return hash_hmac("sha256", $this->config['partner_id'] . $timestamp, $this->config['partner_secret']); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 获取RequestId |
||||
* @return string |
||||
*/ |
||||
private function getRequestId(): string |
||||
{ |
||||
$char_id = strtoupper(md5(uniqid((string)mt_rand(), true))); |
||||
return substr($char_id, 0, 8) |
||||
. substr($char_id, 8, 4) |
||||
. substr($char_id, 12, 4) |
||||
. substr($char_id, 16, 4) |
||||
. substr($char_id, 20, 12); |
||||
} |
||||
|
||||
/** |
||||
* 获取毫秒 |
||||
* @return int |
||||
*/ |
||||
private function getMillisecond(): int |
||||
{ |
||||
[$t1, $t2] = explode(' ', microtime()); |
||||
return (int)sprintf('%.0f', ((float)$t1 + (float)$t2) * 1000); |
||||
} |
||||
|
||||
/** |
||||
* @param string $endpoint |
||||
* @param array $params |
||||
* @param string $method |
||||
* @param array $options |
||||
* @return ResponseInterface|string[] |
||||
*/ |
||||
protected function requestHanle(string $endpoint, array $params = [], string $method = 'post', array $options = []) |
||||
{ |
||||
$timestamp = $this->getMillisecond(); |
||||
$params = array_merge([ |
||||
'base_uri' => $this->host, |
||||
'headers' => [ |
||||
'god-portal-timestamp' => $timestamp, |
||||
'god-portal-request-id' => $this->getRequestId(), |
||||
'god-portal-signature' => $this->getSign((string)$timestamp), |
||||
], |
||||
'json' => $params |
||||
], $options); |
||||
|
||||
try { |
||||
$response = $this->request($endpoint, $method, $params); |
||||
|
||||
$this->writerLog($endpoint, $params, $response); |
||||
|
||||
return $response; |
||||
|
||||
} catch (Exception $e) { |
||||
return [ |
||||
'code' => -1, |
||||
//'message' => "{$e->getMessage()} ON {$e->getFile()}:{$e->getLine()}" |
||||
'message' => $e->getMessage() |
||||
]; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 记录日志 |
||||
* @param string $request_url |
||||
* @param mixed $request_data |
||||
* @param mixed $response |
||||
* @return void |
||||
*/ |
||||
private function writerLog(string $request_url, mixed $request_data, mixed $response): void |
||||
{ |
||||
//写入日志 |
||||
$log_content = [ |
||||
'[REQUEST TIME] ' . date('Y-m-d H:i:s'), |
||||
'[REQUEST URL] ' . $request_url, |
||||
'[REQUEST PARAM] ' . json_encode($request_data, JSON_UNESCAPED_UNICODE), |
||||
'[RESPONSE PARAM] ' . json_encode($response, JSON_UNESCAPED_UNICODE), |
||||
"\r\n", |
||||
]; |
||||
|
||||
recordLog('authorization', implode("\r\n", $log_content)); |
||||
} |
||||
|
||||
/** |
||||
* 获取授权跳转地址 |
||||
* @param string $return_url 回调地址 |
||||
* @return string |
||||
*/ |
||||
public function getAuthRedirectUrl(string $return_url): string |
||||
{ |
||||
$url = '/oauth/code'; |
||||
$data = [ |
||||
'authType' => 2, |
||||
'isDepart' => 2, |
||||
'bizType' => '04107', |
||||
'appid' => $this->config['app_id'], |
||||
'cityCode' => $this->config['city_code'], |
||||
'channel' => $this->config['channel'], |
||||
'orgChnlCrtfCodg' => $this->config['org_chnl_crtf_codg'], |
||||
'orgCodg' => $this->config['org_codg'], |
||||
'orgAppId' => $this->config['org_app_id'], |
||||
'redirectUrl' => $return_url |
||||
]; |
||||
|
||||
$redirect_url = $this->auth_host . $url . '?' . http_build_query($data); |
||||
|
||||
$this->writerLog($url, $data, ''); |
||||
|
||||
return $redirect_url; |
||||
} |
||||
|
||||
/** |
||||
* 查询用户授权 |
||||
* @param string $auth_code |
||||
* @param string $open_id |
||||
* @return ResponseInterface|string[] |
||||
* @throws GuzzleException |
||||
*/ |
||||
public function userQuery(string $auth_code, string $open_id): array|ResponseInterface |
||||
{ |
||||
$uri = '/api/mipuserquery/userQuery/' . $this->config['partner_id']; |
||||
$param = [ |
||||
'qrcode' => $auth_code, |
||||
'openid' => $open_id, |
||||
]; |
||||
|
||||
return $this->requestHanle($uri, $param); |
||||
} |
||||
} |
Loading…
Reference in new issue