170 lines
4.5 KiB
PHP
170 lines
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Entity\Parse\Traits;
|
|
|
|
use App\Model\Model as Entity;
|
|
use App\Model\Platform;
|
|
use Hyperf\Amqp\Message\ConsumerMessageInterface;
|
|
use InvalidArgumentException;
|
|
use Hyperf\Stringable\Str;
|
|
|
|
/**
|
|
* EntityParseHelper Trait
|
|
*
|
|
* 提供通用的消息解析辅助方法
|
|
*/
|
|
trait EntityParseHelper
|
|
{
|
|
/**
|
|
* 从 exchange 名称中提取平台信息
|
|
*
|
|
* 规则:exchange 格式为 "platform.exchange"
|
|
* 例如:tmall.exchange -> Tmall 平台
|
|
*
|
|
* @param ConsumerMessageInterface $message
|
|
* @return Platform
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function extractPlatformFromExchange(ConsumerMessageInterface $message): Platform
|
|
{
|
|
$platformName = Str::of($message->getExchange())
|
|
->before('.')
|
|
->ucfirst()
|
|
->toString();
|
|
|
|
$platform = Platform::where('name', '=', $platformName)->first();
|
|
|
|
if (!$platform) {
|
|
throw new InvalidArgumentException("Platform name '{$platformName}' does not exist!");
|
|
}
|
|
|
|
return $platform;
|
|
}
|
|
|
|
/**
|
|
* 从 routing key 中提取实体类型
|
|
*
|
|
* 规则:routing key 格式为 "entity.platform"
|
|
* 例如:order.tmall -> Order 实体
|
|
*
|
|
* @param ConsumerMessageInterface $message
|
|
* @return Entity
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function extractEntityFromRoutingKey(ConsumerMessageInterface $message): Entity
|
|
{
|
|
$entityName = Str::of($message->getRoutingKey())
|
|
->before('.')
|
|
->ucfirst()
|
|
->toString();
|
|
|
|
$entityClass = "App\\Model\\{$entityName}";
|
|
|
|
if (!class_exists($entityClass)) {
|
|
throw new InvalidArgumentException("Entity class '{$entityClass}' does not exist");
|
|
}
|
|
|
|
$entity = new $entityClass();
|
|
|
|
if (!$entity instanceof Entity) {
|
|
throw new InvalidArgumentException("Class '{$entityClass}' is not an instance of Entity");
|
|
}
|
|
|
|
return $entity;
|
|
}
|
|
|
|
/**
|
|
* 从消息体中提取 JSON 数据
|
|
*
|
|
* @param ConsumerMessageInterface $message
|
|
* @return array
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function extractMessageData(ConsumerMessageInterface $message): array
|
|
{
|
|
$body = $message->getBody();
|
|
|
|
if (empty($body)) {
|
|
throw new InvalidArgumentException('Message body is empty');
|
|
}
|
|
|
|
$data = json_decode($body, true);
|
|
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
throw new InvalidArgumentException('Invalid JSON in message body: ' . json_last_error_msg());
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 从消息数据中提取唯一标识符
|
|
*
|
|
* 优先级:id > unique_id > 其他自定义字段
|
|
*
|
|
* @param array $data
|
|
* @param string|null $customField 自定义标识符字段名
|
|
* @return string|int
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function extractUniqueIdentifier(array $data, ?string $customField = null): string|int
|
|
{
|
|
// 优先使用自定义字段
|
|
if ($customField !== null && isset($data[$customField])) {
|
|
return $data[$customField];
|
|
}
|
|
|
|
// 默认查找 id
|
|
if (isset($data['id'])) {
|
|
return $data['id'];
|
|
}
|
|
|
|
// 查找 unique_id
|
|
if (isset($data['unique_id'])) {
|
|
return $data['unique_id'];
|
|
}
|
|
|
|
throw new InvalidArgumentException('Cannot extract unique identifier from message data');
|
|
}
|
|
|
|
/**
|
|
* 从消息数据中安全地提取字段值
|
|
*
|
|
* @param array $data
|
|
* @param string $field
|
|
* @param mixed $default
|
|
* @return mixed
|
|
*/
|
|
protected function getDataField(array $data, string $field, mixed $default = null): mixed
|
|
{
|
|
return $data[$field] ?? $default;
|
|
}
|
|
|
|
/**
|
|
* 验证消息数据中的必需字段
|
|
*
|
|
* @param array $data
|
|
* @param array $requiredFields
|
|
* @return void
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function validateRequiredFields(array $data, array $requiredFields): void
|
|
{
|
|
$missingFields = [];
|
|
|
|
foreach ($requiredFields as $field) {
|
|
if (!isset($data[$field])) {
|
|
$missingFields[] = $field;
|
|
}
|
|
}
|
|
|
|
if (!empty($missingFields)) {
|
|
throw new InvalidArgumentException(
|
|
'Missing required fields: ' . implode(', ', $missingFields)
|
|
);
|
|
}
|
|
}
|
|
}
|