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