update entiity parse

This commit is contained in:
2025-11-27 15:03:25 +08:00
parent 0d634a2ca9
commit e9068ac73d
7 changed files with 569 additions and 122 deletions
+61 -36
View File
@@ -9,6 +9,7 @@ use Hyperf\Contract\ConfigInterface;
use Hyperf\Stringable\Str;
use InvalidArgumentException;
use Psr\Container\ContainerInterface;
use PhpAmqpLib\Message\AMQPMessage;
/**
* EntityParseFactory 工厂类
@@ -102,66 +103,90 @@ class EntityParseFactory
/**
* 根据消息自动创建 Parser 实例(静态方法)
*
* @param ConsumerMessageInterface $message
* @param string|null $entityType 实体类型(可选,如果不指定则从 routing key 中提取)
* @param AMQPMessage $message
* @param string|null $entityType 实体类型(可选,如果不指定则从 payload 中提取)
* @return EntityParseInterface
* @throws InvalidArgumentException
*/
public static function createFromMessage(
ConsumerMessageInterface $message,
AMQPMessage $message,
?string $entityType = null
): EntityParseInterface {
// 1. 从 exchange 中提取平台名称
$platformName = self::extractPlatformName($message);
// 1. 从消息体中解析数据
$data = json_decode($message->getBody(), true);
// 2. 如果未指定实体类型,从 routing key 中提取
if ($entityType === null) {
$entityType = self::extractEntityType($message);
if (!is_array($data)) {
throw new InvalidArgumentException('Invalid message body: expected JSON array');
}
// 3. 获取对应的 Parser 类
// 2. 从 data 中提取平台名称
$platformName = self::extractPlatformNameFromData($data);
// 3. 如果未指定实体类型,从 data 或 routing key 中提取
if ($entityType === null) {
$entityType = self::extractEntityTypeFromData($data, $message);
}
// 4. 获取对应的 Parser 类
$parserClass = self::resolveParserClass($platformName, $entityType);
// 4. 创建并返回 Parser 实例
return $parserClass::create($message);
// 5. 创建并返回 Parser 实例,传递解析后的数据
return $parserClass::create($data);
}
/**
* 从 exchange 中提取平台名称
* 从数据中提取平台名称
*
* 规则:exchange 格式为 "platform.exchange"
* 例如:tmall.exchange -> tmall
*
* @param ConsumerMessageInterface $message
* @param array $data
* @return string
*/
private static function extractPlatformName(ConsumerMessageInterface $message): string
private static function extractPlatformNameFromData(array $data): string
{
$exchange = $message->getExchange();
$platformName = Str::of($exchange)
->before('.')
->lower()
->toString();
if (empty($platformName)) {
throw new InvalidArgumentException("Cannot extract platform name from exchange: {$exchange}");
// 优先从 platform_id 获取,如果没有则尝试从其他字段获取
if (isset($data['platform_id'])) {
// 这里可以根据 platform_id 映射到平台名称
// 简化处理:假设需要从数据库或配置中查找
// 当前先直接使用 platform_id 作为平台名称
return self::resolvePlatformName($data['platform_id']);
}
return $platformName;
throw new InvalidArgumentException("Cannot extract platform name from data: platform_id missing");
}
/**
* 从 routing key 中提取实体类型
* 根据 platform_id 解析平台名称
*
* 规则:routing key 格式为 "entity.action"
* 例如:order.create -> order
*
* @param ConsumerMessageInterface $message
* @param mixed $platformId
* @return string
*/
private static function extractEntityType(ConsumerMessageInterface $message): string
private static function resolvePlatformName($platformId): string
{
// TODO: 从配置或数据库中根据 platform_id 查找平台名称
// 临时方案:使用简单的映射
$platformMap = [
1 => 'taobao',
2 => 'tmall',
3 => 'jd',
// ... 其他平台
];
if (isset($platformMap[$platformId])) {
return $platformMap[$platformId];
}
throw new InvalidArgumentException("Unknown platform_id: {$platformId}");
}
/**
* 从数据或路由键中提取实体类型
*
* @param array $data
* @param AMQPMessage $message
* @return string
*/
private static function extractEntityTypeFromData(array $data, AMQPMessage $message): string
{
// 优先从 routing key 中提取
$routingKey = $message->getRoutingKey();
$entityType = Str::of($routingKey)
@@ -169,11 +194,11 @@ class EntityParseFactory
->lower()
->toString();
if (empty($entityType)) {
throw new InvalidArgumentException("Cannot extract entity type from routing key: {$routingKey}");
if (!empty($entityType)) {
return $entityType;
}
return $entityType;
throw new InvalidArgumentException("Cannot extract entity type from routing key: {$routingKey}");
}
/**