add entity parse constraint
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Platform;
|
||||
|
||||
interface AdapterInterface
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Platform;
|
||||
|
||||
use App\Model\Model as Entity;
|
||||
use App\Model\Company;
|
||||
use App\Model\Platform;
|
||||
use App\Model\Store;
|
||||
use Hyperf\Amqp\Message\ConsumerMessageInterface;
|
||||
use Psr\Log\InvalidArgumentException;
|
||||
use Hyperf\Stringable\Str;
|
||||
|
||||
abstract class EntityParse implements EntityParseInterface
|
||||
{
|
||||
private ?ConsumerMessageInterface $message = null;
|
||||
private ?Platform $platform = null;
|
||||
private ?Company $company = null;
|
||||
private ?Store $store = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->platform = $this->platformScopeMatch($this->message);
|
||||
$this->company = $this->companyScopeMatch($this->message);
|
||||
$this->store = $this->storeScopeMatch($this->message);
|
||||
|
||||
if(!$this->platform instanceof Platform || !isset($this->platform->id)){
|
||||
throw new InvalidArgumentException('platform is undefined');
|
||||
}
|
||||
|
||||
if(!$this->company instanceof Platform || !isset($this->company->id)){
|
||||
throw new InvalidArgumentException('company is undefined');
|
||||
}
|
||||
|
||||
if(!$this->store instanceof Platform || !isset($this->store->id)){
|
||||
throw new InvalidArgumentException('store is undefined');
|
||||
}
|
||||
}
|
||||
|
||||
public function companyScopeMatch(ConsumerMessageInterface $message): Company
|
||||
{
|
||||
// TODO: Implement companyScopeMatch() method.
|
||||
}
|
||||
|
||||
public function platformScopeMatch(ConsumerMessageInterface $message): Platform
|
||||
{
|
||||
$platformName = Str::of($message->getExchange())->before('.')->ucfirst()->toString();
|
||||
|
||||
$platform = Platform::where('name','=',$platformName)->first();
|
||||
|
||||
// 确保实例化的对象是 Entity 类型
|
||||
if (!$platform) {
|
||||
throw new InvalidArgumentException("PLatform name {$platformName} not exist!");
|
||||
}
|
||||
|
||||
return $platform;
|
||||
|
||||
}
|
||||
|
||||
public function storeScopeMatch(ConsumerMessageInterface $message): Store
|
||||
{
|
||||
// TODO: Implement storeScopeMatch() method.
|
||||
}
|
||||
|
||||
public function entityMatch(ConsumerMessageInterface $message): Entity
|
||||
{
|
||||
// 从路由键中提取实体名称,例如 'order.tmall' -> 'Order'
|
||||
$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();
|
||||
|
||||
// 确保实例化的对象是 Entity 类型
|
||||
if (!$entity instanceof Entity) {
|
||||
throw new InvalidArgumentException("Class {$entityClass} is not an instance of Entity");
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public function entityMap(array $data, Entity $entity): Entity
|
||||
{
|
||||
// TODO: Implement entityMap() method.
|
||||
// entityMap 方法应该返回一个 属性已被更新设置的数据模型,而非默认空状态的 Entity
|
||||
|
||||
return $this->entityMatch($this->message);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Platform;
|
||||
|
||||
use Hyperf\Amqp\Message\ConsumerMessageInterface;
|
||||
use App\Model\Company;
|
||||
use App\Model\Platform;
|
||||
use App\Model\Store;
|
||||
use App\Model\Model as Entity;
|
||||
|
||||
interface EntityParseInterface
|
||||
{
|
||||
public function companyScopeMatch(ConsumerMessageInterface $message) : Company;
|
||||
|
||||
public function platformScopeMatch(ConsumerMessageInterface $message) : Platform;
|
||||
|
||||
public function storeScopeMatch(ConsumerMessageInterface $message) : Store;
|
||||
|
||||
public function entityMatch(ConsumerMessageInterface $message) : Entity;
|
||||
|
||||
public function entityMap(array $data, Entity $entity): Entity;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Platform\Tmall;
|
||||
|
||||
use App\Model\Company;
|
||||
use App\Model\Model as Entity;
|
||||
use App\Model\Store;
|
||||
use App\Entity\Parse\EntityParse;
|
||||
use Hyperf\Amqp\Message\ConsumerMessageInterface;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* 天猫订单解析器示例
|
||||
*
|
||||
* 展示如何继承 EntityParse 实现自定义解析逻辑
|
||||
*/
|
||||
class TmallOrderParser extends EntityParse
|
||||
{
|
||||
/**
|
||||
* 公司作用域匹配
|
||||
*
|
||||
* 从消息体中提取 company_id,然后查询数据库获取公司对象
|
||||
*
|
||||
* @param ConsumerMessageInterface $message
|
||||
* @return Company
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function companyScopeMatch(ConsumerMessageInterface $message): Company
|
||||
{
|
||||
$data = $this->extractMessageData($message);
|
||||
|
||||
// 验证必需字段
|
||||
$this->validateRequiredFields($data, ['company_id']);
|
||||
|
||||
$companyId = $data['company_id'];
|
||||
|
||||
$company = Company::find($companyId);
|
||||
|
||||
if (!$company) {
|
||||
throw new InvalidArgumentException("Company with ID {$companyId} not found");
|
||||
}
|
||||
|
||||
return $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* 店铺作用域匹配
|
||||
*
|
||||
* 从消息体中提取 store_id,然后查询数据库获取店铺对象
|
||||
*
|
||||
* @param ConsumerMessageInterface $message
|
||||
* @return Store
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function storeScopeMatch(ConsumerMessageInterface $message): Store
|
||||
{
|
||||
$data = $this->extractMessageData($message);
|
||||
|
||||
// 验证必需字段
|
||||
$this->validateRequiredFields($data, ['store_id']);
|
||||
|
||||
$storeId = $data['store_id'];
|
||||
|
||||
$store = Store::find($storeId);
|
||||
|
||||
if (!$store) {
|
||||
throw new InvalidArgumentException("Store with ID {$storeId} not found");
|
||||
}
|
||||
|
||||
return $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体数据映射
|
||||
*
|
||||
* 将原始数据映射到实体对象
|
||||
*
|
||||
* @param array $data
|
||||
* @param Entity $entity
|
||||
* @return Entity
|
||||
*/
|
||||
public function entityMap(array $data, Entity $entity): Entity
|
||||
{
|
||||
// 假设数据结构为:
|
||||
// {
|
||||
// "platform_id": 2,
|
||||
// "company_id": 188,
|
||||
// "store_id": 292,
|
||||
// "unique_id": "abc123",
|
||||
// "raw_data": [...]
|
||||
// }
|
||||
|
||||
$rawData = $data['raw_data'] ?? [];
|
||||
|
||||
// 映射基本信息
|
||||
$entity->platform_id = $this->getPlatform()->id;
|
||||
$entity->company_id = $this->getCompany()->id;
|
||||
$entity->store_id = $this->getStore()->id;
|
||||
$entity->unique_id = $data['unique_id'] ?? null;
|
||||
|
||||
// 映射原始数据
|
||||
if (!empty($rawData)) {
|
||||
$entity->raw_data = json_encode($rawData);
|
||||
}
|
||||
|
||||
// 映射其他字段(根据实际业务需求)
|
||||
// ...
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可选:覆盖唯一标识符提取逻辑
|
||||
*
|
||||
* 如果使用默认的 id/unique_id 提取逻辑,则无需覆盖此方法
|
||||
*/
|
||||
// public function entityUniqueIdentifierExtract(ConsumerMessageInterface $message): string|int
|
||||
// {
|
||||
// $data = $this->extractMessageData($message);
|
||||
// return $this->extractUniqueIdentifier($data, 'custom_id_field');
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user