|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace App\Utils\Transfer;
|
|
|
|
|
|
|
|
use Exception;
|
|
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
|
|
use Illuminate\Support\Facades\Config;
|
|
|
|
use GuzzleHttp\Client;
|
|
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
|
|
|
|
abstract class HttpTransferAbstract
|
|
|
|
{
|
|
|
|
// HTTP 客户端
|
|
|
|
private Client $client;
|
|
|
|
|
|
|
|
// His接口配置数据
|
|
|
|
private array $his_config;
|
|
|
|
|
|
|
|
// 调用方法
|
|
|
|
public string $transfer_method;
|
|
|
|
|
|
|
|
// 调用接口名称
|
|
|
|
public string $transfer_name;
|
|
|
|
|
|
|
|
// 调用接口参数
|
|
|
|
public mixed $transfer_parameter;
|
|
|
|
|
|
|
|
// 调用返回结果 string格式用于mock数据
|
|
|
|
public ResponseInterface|string $transfer_response;
|
|
|
|
|
|
|
|
// 运行时间
|
|
|
|
public array $request_time;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* HttpTransferAbstract constructor.
|
|
|
|
* @param string $his_name
|
|
|
|
*/
|
|
|
|
public function __construct(string $his_name)
|
|
|
|
{
|
|
|
|
$config = Config::get('hisservice.'. $his_name);
|
|
|
|
|
|
|
|
// 获取配置文件中的接口配置信息
|
|
|
|
$this->his_config = $config;
|
|
|
|
$this->his_config['his_name'] = $his_name;
|
|
|
|
|
|
|
|
$this->initialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 初始化
|
|
|
|
*/
|
|
|
|
public function initialize(): void
|
|
|
|
{
|
|
|
|
$headers = $this->clientHeaders();
|
|
|
|
$this->client = new Client([
|
|
|
|
'base_uri' => $this->his_config['url'],
|
|
|
|
'headers' => $headers,
|
|
|
|
... $this->his_config['options']
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取配置
|
|
|
|
* @param string $key
|
|
|
|
* @return mixed|null
|
|
|
|
*/
|
|
|
|
public function getHisConfigByKey(string $key): mixed
|
|
|
|
{
|
|
|
|
if (isset($this->his_config[$key])) {
|
|
|
|
return $this->his_config[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 设置客户端 Header 头
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
abstract public function clientHeaders(): array;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 需要调用的方法
|
|
|
|
* @param string $method
|
|
|
|
* @param string $request_name
|
|
|
|
* @param array $request_data
|
|
|
|
* @return $this
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function transferMethod(string $method, string $request_name, array $request_data = []): self
|
|
|
|
{
|
|
|
|
// 记录调用的接口名称和参数
|
|
|
|
$this->transfer_method = $method;
|
|
|
|
$this->transfer_name = $request_name;
|
|
|
|
$this->transfer_parameter = $request_data;
|
|
|
|
|
|
|
|
try {
|
|
|
|
// 发送 HTTP 请求
|
|
|
|
$this->request_time['start_time'] = microtime(true);
|
|
|
|
$this->transfer_response = $this->client->request($method, $this->transfer_name, $this->transfer_parameter);
|
|
|
|
$this->request_time['end_time'] = microtime(true);
|
|
|
|
} catch (GuzzleException|Exception $e) {
|
|
|
|
!isset($this->request_time['end_time']) && $this->request_time['end_time'] = microtime(true);
|
|
|
|
$this->recordLog();
|
|
|
|
throw new Exception("{$e->getFile()}:{$e->getLine()}:{$e->getMessage()}");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 记录日志
|
|
|
|
$this->recordLog();
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取返回值
|
|
|
|
* @param bool $is_format
|
|
|
|
* @return mixed
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function getResult(bool $is_format = true): mixed
|
|
|
|
{
|
|
|
|
if ($is_format) {
|
|
|
|
return $this->responseFormat($this->transfer_response);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->transfer_response;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 响应格式化
|
|
|
|
* @param mixed $data
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
abstract public function responseFormat(mixed $data): mixed;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 魔术方法实现动态调用方法
|
|
|
|
* @param $function
|
|
|
|
* @param $args
|
|
|
|
* @return $this
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function __call($function, $args): self
|
|
|
|
{
|
|
|
|
if (method_exists($this, $function)) {
|
|
|
|
throw new Exception(__CLASS__ . '类的"'. $function .'"方法不存在');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->client = call_user_func($function, ...$args);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 记录日志
|
|
|
|
*/
|
|
|
|
public function recordLog(): void
|
|
|
|
{
|
|
|
|
// 判断“是否设置日志参数”和“当前调用的方法是否记录到日志”
|
|
|
|
if (!empty($this->transfer_name)) {
|
|
|
|
$run_time = sprintf("%.6f", ($this->request_time['end_time'] - $this->request_time['start_time']));
|
|
|
|
|
|
|
|
if (
|
|
|
|
empty($this->his_config['not_log_arr']) ||
|
|
|
|
!in_array($this->transfer_name, $this->his_config['not_log_arr'])
|
|
|
|
) {
|
|
|
|
// 记录入参和结果
|
|
|
|
$content = '[METHOD NAME] '. $this->transfer_method. '|'. $this->transfer_name. PHP_EOL.
|
|
|
|
'[REQUEST PARAM] '. json_encode($this->transfer_parameter, JSON_UNESCAPED_UNICODE). PHP_EOL.
|
|
|
|
'[RESPONSE PARAM] '. json_encode($this->transfer_response, JSON_UNESCAPED_UNICODE). PHP_EOL.
|
|
|
|
'[RUN TIME] '. $run_time . "/s";
|
|
|
|
$this->recordRequestLog($this->his_config['his_name'], $content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 保存日志记录
|
|
|
|
* @param string $his_name
|
|
|
|
* @param string $content
|
|
|
|
*/
|
|
|
|
protected function recordRequestLog(string $his_name, string $content): void
|
|
|
|
{
|
|
|
|
date_default_timezone_set("Asia/Shanghai");
|
|
|
|
|
|
|
|
$dirname = $this->his_config['his_name'];
|
|
|
|
$path = app()->storagePath(). DIRECTORY_SEPARATOR. $dirname. DIRECTORY_SEPARATOR;
|
|
|
|
$file_path = $path. $his_name. 'Log'. DIRECTORY_SEPARATOR. date('Ym'). DIRECTORY_SEPARATOR;
|
|
|
|
$file_name = date('d'). ".log";
|
|
|
|
|
|
|
|
!is_dir($file_path) && mkdir($file_path, 0755, true);
|
|
|
|
|
|
|
|
$msg = "[".date('Y-m-d H:i:s')."]". PHP_EOL . $content . PHP_EOL . PHP_EOL;
|
|
|
|
|
|
|
|
file_put_contents( $file_path. $file_name, $msg, FILE_APPEND);
|
|
|
|
}
|
|
|
|
}
|