封装优化
This commit is contained in:
@@ -7,8 +7,8 @@ namespace App\Controller;
|
|||||||
use Aether\AetherController;
|
use Aether\AetherController;
|
||||||
use Aether\AetherResponse;
|
use Aether\AetherResponse;
|
||||||
use App\Exception\BusinessException;
|
use App\Exception\BusinessException;
|
||||||
use App\Model\Campus;
|
use Aether\Campus;
|
||||||
use App\Validator\CampusValidator;
|
use Aether\CampusValidator;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Hyperf\Di\Annotation\Inject;
|
use Hyperf\Di\Annotation\Inject;
|
||||||
use Hyperf\HttpServer\Annotation\Controller;
|
use Hyperf\HttpServer\Annotation\Controller;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ namespace App\Controller;
|
|||||||
use Aether\AetherController;
|
use Aether\AetherController;
|
||||||
use Aether\AetherResponse;
|
use Aether\AetherResponse;
|
||||||
use App\Exception\BusinessException;
|
use App\Exception\BusinessException;
|
||||||
use App\Model\Teacher;
|
use Aether\Teacher;
|
||||||
use App\Validator\TeacherValidator;
|
use Aether\TeacherValidator;
|
||||||
use Hyperf\Di\Annotation\Inject;
|
use Hyperf\Di\Annotation\Inject;
|
||||||
use Hyperf\HttpServer\Annotation\Controller;
|
use Hyperf\HttpServer\Annotation\Controller;
|
||||||
use Hyperf\HttpServer\Annotation\DeleteMapping;
|
use Hyperf\HttpServer\Annotation\DeleteMapping;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace App\JsonRpc\Service;
|
namespace App\JsonRpc\Service;
|
||||||
|
|
||||||
use Aether\Exception\BusinessException;
|
use Aether\Exception\BusinessException;
|
||||||
use App\Model\Campus;
|
use Aether\Campus;
|
||||||
use Hyperf\RpcServer\Annotation\RpcService;
|
use Hyperf\RpcServer\Annotation\RpcService;
|
||||||
use MicroService\Contract\CampusServiceInterface;
|
use MicroService\Contract\CampusServiceInterface;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace App\JsonRpc\Service;
|
namespace App\JsonRpc\Service;
|
||||||
|
|
||||||
use Aether\Exception\BusinessException;
|
use Aether\Exception\BusinessException;
|
||||||
use App\Model\Teacher;
|
use Aether\Teacher;
|
||||||
use Hyperf\RpcServer\Annotation\RpcService;
|
use Hyperf\RpcServer\Annotation\RpcService;
|
||||||
use MicroService\Contract\TeacherServiceInterface;
|
use MicroService\Contract\TeacherServiceInterface;
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ return [
|
|||||||
'handler' => [
|
'handler' => [
|
||||||
'http' => [
|
'http' => [
|
||||||
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
|
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
|
||||||
App\Exception\Handler\AppExceptionHandler::class,
|
Aether\AppExceptionHandler::class,
|
||||||
],
|
],
|
||||||
'jsonrpc-http' => [
|
'jsonrpc-http' => [
|
||||||
//Aether\Exception\AppExceptionHandler::class,
|
//Aether\Exception\AppExceptionHandler::class,
|
||||||
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
|
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
|
||||||
App\Exception\Handler\AppExceptionHandler::class,
|
Aether\AppExceptionHandler::class,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
101
extend/Aether/PHP/Hyperf/AbstractModel.php
Normal file
101
extend/Aether/PHP/Hyperf/AbstractModel.php
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Hyperf\Database\Model\Builder;
|
||||||
|
use Hyperf\Database\Model\ModelNotFoundException;
|
||||||
|
use Hyperf\Database\Model\SoftDeletes;
|
||||||
|
|
||||||
|
abstract class AbstractModel extends AetherModel
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳字段格式
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
protected ?string $dateFormat = 'Y-m-d H:i:s';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可批量赋值的字段
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $fillable = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期字段
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $dates = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'deleted_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段类型转换
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $casts = [
|
||||||
|
'id' => 'integer',
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
'deleted_at' => 'datetime',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用状态查询作用域
|
||||||
|
*/
|
||||||
|
public function scopeEnabled(Builder $query): Builder
|
||||||
|
{
|
||||||
|
return $query->where('status', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按ID查询并检查存在性
|
||||||
|
* @param int $id
|
||||||
|
* @param array $columns
|
||||||
|
* @return AbstractModel
|
||||||
|
*/
|
||||||
|
public static function findOrFail(int $id, $columns = []): self
|
||||||
|
{
|
||||||
|
$model = self::find($id);
|
||||||
|
if (!$model) {
|
||||||
|
throw new ModelNotFoundException();
|
||||||
|
}
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建记录并返回实例
|
||||||
|
*/
|
||||||
|
public static function createOne(array $data): self
|
||||||
|
{
|
||||||
|
$model = new static();
|
||||||
|
$model->fill($data);
|
||||||
|
$model->save();
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新记录
|
||||||
|
*/
|
||||||
|
public static function updateById(int $id, array $data): bool
|
||||||
|
{
|
||||||
|
$model = self::findOrFail($id);
|
||||||
|
return $model->update($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除记录
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function deleteById(int $id): bool
|
||||||
|
{
|
||||||
|
$model = self::findOrFail($id);
|
||||||
|
return $model->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
147
extend/Aether/PHP/Hyperf/AbstractService.php
Normal file
147
extend/Aether/PHP/Hyperf/AbstractService.php
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether;
|
||||||
|
|
||||||
|
use App\Exception\BusinessException;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\Logger\LoggerFactory;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
abstract class AbstractService
|
||||||
|
{
|
||||||
|
#[Inject]
|
||||||
|
protected LoggerFactory $loggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
protected LoggerInterface $logger;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->logger = $this->loggerFactory->get($this->getLoggerName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取资源列表
|
||||||
|
*/
|
||||||
|
public function list(array $params = []): array
|
||||||
|
{
|
||||||
|
$this->validateQuery($params);
|
||||||
|
return $this->getModel()::query()
|
||||||
|
->when(isset($params['page']), function ($query) use ($params) {
|
||||||
|
$page = (int)($params['page'] ?? 1);
|
||||||
|
$size = (int)($params['size'] ?? 20);
|
||||||
|
return $query->forPage($page, $size);
|
||||||
|
})
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取资源详情
|
||||||
|
*/
|
||||||
|
public function detail(int $id): array
|
||||||
|
{
|
||||||
|
$model = $this->getModel()::find($id);
|
||||||
|
if (!$model) {
|
||||||
|
throw new BusinessException(404, '资源不存在');
|
||||||
|
}
|
||||||
|
return $model->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建资源
|
||||||
|
*/
|
||||||
|
public function create(array $data): int
|
||||||
|
{
|
||||||
|
$this->validateCreate($data);
|
||||||
|
$model = $this->getModel()::create($data);
|
||||||
|
$this->logger->info('资源创建成功', ['id' => $model->id, 'data' => $data]);
|
||||||
|
return $model->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新资源
|
||||||
|
*/
|
||||||
|
public function update(int $id, array $data): bool
|
||||||
|
{
|
||||||
|
$this->validateUpdate($data);
|
||||||
|
$model = $this->getModel()::find($id);
|
||||||
|
if (!$model) {
|
||||||
|
throw new BusinessException(404, '资源不存在');
|
||||||
|
}
|
||||||
|
$result = $model->update($data);
|
||||||
|
$this->logger->info('资源更新成功', ['id' => $id, 'data' => $data]);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除资源
|
||||||
|
*/
|
||||||
|
public function delete(int $id): bool
|
||||||
|
{
|
||||||
|
$model = $this->getModel()::find($id);
|
||||||
|
if (!$model) {
|
||||||
|
throw new BusinessException(404, '资源不存在');
|
||||||
|
}
|
||||||
|
$result = $model->delete();
|
||||||
|
$this->logger->info('资源删除成功', ['id' => $id]);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证查询参数
|
||||||
|
*/
|
||||||
|
protected function validateQuery(array $params): void
|
||||||
|
{
|
||||||
|
$validator = $this->getValidator()->scene('query', $params);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new BusinessException(400, $validator->errors()->first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证创建参数
|
||||||
|
*/
|
||||||
|
protected function validateCreate(array $data): void
|
||||||
|
{
|
||||||
|
$validator = $this->getValidator()->scene('create', $data);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new BusinessException(400, $validator->errors()->first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证更新参数
|
||||||
|
*/
|
||||||
|
protected function validateUpdate(array $data): void
|
||||||
|
{
|
||||||
|
$validator = $this->getValidator()->scene('update', $data);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new BusinessException(400, $validator->errors()->first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取日志名称
|
||||||
|
*/
|
||||||
|
protected function getLoggerName(): string
|
||||||
|
{
|
||||||
|
return strtolower((new \ReflectionClass($this))->getShortName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对应的模型类
|
||||||
|
* @return AbstractModel
|
||||||
|
*/
|
||||||
|
abstract protected function getModel(): AbstractModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对应的验证器类
|
||||||
|
* @return AbstractValidator
|
||||||
|
*/
|
||||||
|
abstract protected function getValidator(): AbstractValidator;
|
||||||
|
}
|
||||||
67
extend/Aether/PHP/Hyperf/AbstractValidator.php
Normal file
67
extend/Aether/PHP/Hyperf/AbstractValidator.php
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether;
|
||||||
|
|
||||||
|
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
|
||||||
|
use Hyperf\Validation\Validator;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
|
||||||
|
abstract class AbstractValidator
|
||||||
|
{
|
||||||
|
#[Inject]
|
||||||
|
protected ValidatorFactoryInterface $validationFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证场景规则
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $scenes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认验证规则
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $rules = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证消息
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $messages = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 属性名称
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected array $attributes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证器实例
|
||||||
|
*/
|
||||||
|
public function scene(string $scene, array $data): Validator
|
||||||
|
{
|
||||||
|
$rules = $this->getSceneRules($scene);
|
||||||
|
return $this->validationFactory->make($data, $rules, $this->messages, $this->attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取场景验证规则
|
||||||
|
*/
|
||||||
|
protected function getSceneRules(string $scene): array
|
||||||
|
{
|
||||||
|
if (empty($this->scenes[$scene])) {
|
||||||
|
return $this->rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sceneRules = [];
|
||||||
|
foreach ($this->scenes[$scene] as $field) {
|
||||||
|
if (isset($this->rules[$field])) {
|
||||||
|
$sceneRules[$field] = $this->rules[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sceneRules;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,30 +20,59 @@ abstract class AetherController
|
|||||||
#[Inject]
|
#[Inject]
|
||||||
protected ResponseInterface $response;
|
protected ResponseInterface $response;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取请求参数.
|
* 获取资源列表 (RESTFul: GET /resources)
|
||||||
* @param string $key
|
|
||||||
* @param mixed|null $default
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function requestParam(string $key, mixed $default = null): mixed
|
public function index(): array
|
||||||
{
|
{
|
||||||
return $this->request->input($key, $default);
|
$params = $this->request->all();
|
||||||
|
$result = $this->getService()->list($params);
|
||||||
|
return AetherResponse::success($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有请求参数.
|
* 获取单个资源 (RESTFul: GET /resources/{id})
|
||||||
*/
|
*/
|
||||||
public function requestParams(): array
|
public function show(int $id): array
|
||||||
{
|
{
|
||||||
return $this->request->all();
|
$result = $this->getService()->detail($id);
|
||||||
|
return AetherResponse::success($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回JSON响应.
|
* 创建资源 (RESTFul: POST /resources)
|
||||||
*/
|
*/
|
||||||
public function json(array $data): \Psr\Http\Message\ResponseInterface
|
public function store()
|
||||||
{
|
{
|
||||||
return $this->response->json($data);
|
$data = $this->request->all();
|
||||||
|
$id = $this->getService()->create($data);
|
||||||
|
return AetherResponse::success(['id' => $id], '创建成功');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新资源 (RESTFul: PUT /resources/{id})
|
||||||
|
*/
|
||||||
|
public function update(int $id): array
|
||||||
|
{
|
||||||
|
$data = $this->request->all();
|
||||||
|
$this->getService()->update($id, $data);
|
||||||
|
return AetherResponse::success(null, '更新成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除资源 (RESTFul: DELETE /resources/{id})
|
||||||
|
*/
|
||||||
|
public function destroy(int $id): array
|
||||||
|
{
|
||||||
|
$this->getService()->delete($id);
|
||||||
|
return AetherResponse::success(null, '删除成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对应的服务类
|
||||||
|
* @return \Aether\AbstractService
|
||||||
|
*/
|
||||||
|
abstract protected function getService();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
42
extend/Aether/PHP/Hyperf/ApiExceptionHandler.php
Normal file
42
extend/Aether/PHP/Hyperf/ApiExceptionHandler.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether;
|
||||||
|
|
||||||
|
use function Hyperf\Support\env;
|
||||||
|
use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||||
|
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||||
|
use Psr\Http\Message\MessageInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Throwable;
|
||||||
|
use Hyperf\Context\Context;
|
||||||
|
|
||||||
|
class ApiExceptionHandler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
public function handle(Throwable $throwable, ResponseInterface $response): MessageInterface|ResponseInterface
|
||||||
|
{
|
||||||
|
// 格式化输出
|
||||||
|
$data = [
|
||||||
|
'code' => $throwable->getCode() ?: 500,
|
||||||
|
'message' => $throwable->getMessage() ?: '服务器内部错误',
|
||||||
|
'request_id' => Context::get('request_id', ''),
|
||||||
|
'timestamp' => time(),
|
||||||
|
];
|
||||||
|
|
||||||
|
// 开发环境显示堆栈信息
|
||||||
|
if (env('APP_ENV') === 'dev') {
|
||||||
|
$data['trace'] = $throwable->getTraceAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||||
|
return $response->withHeader('Content-Type', 'application/json')
|
||||||
|
->withStatus($data['code'] >= 400 && $data['code'] < 500 ? $data['code'] : 500)
|
||||||
|
->withBody(new SwooleStream($body));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid(Throwable $throwable): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
extend/Aether/PHP/Hyperf/Middleware/Cors.php
Normal file
29
extend/Aether/PHP/Hyperf/Middleware/Cors.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether\Middleware;
|
||||||
|
|
||||||
|
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
|
||||||
|
class Cors implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected HttpResponse $response)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
|
{
|
||||||
|
$response = $handler->handle($request);
|
||||||
|
|
||||||
|
return $response
|
||||||
|
->withHeader('Access-Control-Allow-Origin', '*')
|
||||||
|
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
||||||
|
->withHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')
|
||||||
|
->withHeader('Access-Control-Max-Age', '86400');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ class RequestId implements MiddlewareInterface
|
|||||||
{
|
{
|
||||||
$requestId = $request->getHeaderLine('X-Request-Id') ?: uniqid();
|
$requestId = $request->getHeaderLine('X-Request-Id') ?: uniqid();
|
||||||
Context::set('request_id', $requestId);
|
Context::set('request_id', $requestId);
|
||||||
var_dump('requestId: ' . $requestId);
|
|
||||||
$response = $handler->handle($request);
|
$response = $handler->handle($request);
|
||||||
return $response->withHeader('X-Request-Id', $requestId);
|
return $response->withHeader('X-Request-Id', $requestId);
|
||||||
}
|
}
|
||||||
|
|||||||
23
extend/Aether/PHP/Hyperf/Middleware/Trace.php
Normal file
23
extend/Aether/PHP/Hyperf/Middleware/Trace.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether\Middleware;
|
||||||
|
|
||||||
|
use Hyperf\Context\Context;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
|
||||||
|
class Trace implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
|
{
|
||||||
|
$requestId = $request->getHeaderLine('X-Request-Id') ?: uniqid();
|
||||||
|
Context::set('request_id', $requestId);
|
||||||
|
|
||||||
|
$response = $handler->handle($request);
|
||||||
|
return $response->withHeader('X-Request-Id', $requestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
extend/Aether/PHP/Hyperf/RpcExceptionHandler.php
Normal file
34
extend/Aether/PHP/Hyperf/RpcExceptionHandler.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aether;
|
||||||
|
|
||||||
|
use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||||
|
use Hyperf\Rpc\Protocol;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Throwable;
|
||||||
|
use Hyperf\Context\Context;
|
||||||
|
|
||||||
|
class RpcExceptionHandler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
|
||||||
|
{
|
||||||
|
// 微服务间调用返回更精简的错误信息
|
||||||
|
$data = [
|
||||||
|
'code' => $throwable->getCode() ?: 500,
|
||||||
|
'message' => $throwable->getMessage() ?: '服务调用失败',
|
||||||
|
'request_id' => Context::get('request_id', ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
$protocol = make(Protocol::class);
|
||||||
|
$response->getBody()->write($protocol->pack($data));
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid(Throwable $throwable): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user