Files
datahub/backend/app/Entity/Parse/Traits/EntityParseHelper.php
T

172 lines
4.4 KiB
PHP
Raw Normal View History

2025-11-27 13:40:58 +08:00
<?php
declare(strict_types=1);
namespace App\Entity\Parse\Traits;
use App\Model\Model as Entity;
use App\Model\Platform;
use InvalidArgumentException;
use Hyperf\Stringable\Str;
2026-01-30 13:30:17 +08:00
use PhpAmqpLib\Message\AMQPMessage;
2025-11-27 13:40:58 +08:00
/**
* EntityParseHelper Trait
*
* 提供通用的消息解析辅助方法
*/
trait EntityParseHelper
{
/**
2026-01-30 13:30:17 +08:00
* 从消息体中提取平台信息
2025-11-27 13:40:58 +08:00
*
2026-01-30 13:30:17 +08:00
* 从消息体的 meta.platform_id 获取平台 ID,查询 Platform
2025-11-27 13:40:58 +08:00
*
2026-01-30 13:30:17 +08:00
* @param AMQPMessage $message
2025-11-27 13:40:58 +08:00
* @return Platform
* @throws InvalidArgumentException
*/
2026-01-30 13:30:17 +08:00
protected function extractPlatformFromExchange(AMQPMessage $message): Platform
2025-11-27 13:40:58 +08:00
{
2026-01-30 13:30:17 +08:00
$data = json_decode($message->getBody(), true);
$platformId = $data['meta']['platform_id'] ?? null;
if (!$platformId) {
throw new InvalidArgumentException("Missing platform_id in message meta");
}
2025-11-27 13:40:58 +08:00
2026-01-30 13:30:17 +08:00
$platform = Platform::find($platformId);
2025-11-27 13:40:58 +08:00
if (!$platform) {
2026-01-30 13:30:17 +08:00
throw new InvalidArgumentException("Platform with id '{$platformId}' does not exist!");
2025-11-27 13:40:58 +08:00
}
return $platform;
}
/**
* 从 routing key 中提取实体类型
*
* 规则:routing key 格式为 "entity.platform"
* 例如:order.tmall -> Order 实体
*
2026-01-30 13:30:17 +08:00
* @param AMQPMessage $message
2025-11-27 13:40:58 +08:00
* @return Entity
* @throws InvalidArgumentException
*/
2026-01-30 13:30:17 +08:00
protected function extractEntityFromRoutingKey(AMQPMessage $message): Entity
2025-11-27 13:40:58 +08:00
{
$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 数据
*
2026-01-30 13:30:17 +08:00
* @param AMQPMessage $message
2025-11-27 13:40:58 +08:00
* @return array
* @throws InvalidArgumentException
*/
2026-01-30 13:30:17 +08:00
protected function extractMessageData(AMQPMessage $message): array
2025-11-27 13:40:58 +08:00
{
$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)
);
}
}
}