浏览代码

feat(logistics): implement logistics interface and caching for tracking data

- Add LogisticsInterface implementation to ExtensionWuLiuEntity
- Provide logisticsInformation method with caching and signature check
- Extract queryLogistics method to centralize external API calls
- Return LogisticsInformationResponse with updated or cached data
- Bind LogisticsInterface to ExtensionWuLiuEntity in Extension::boot() for DI
- Ensure frequent query protection with time limit checks in query process
runphp 5 月之前
父节点
当前提交
311f0e5d97
共有 2 个文件被更改,包括 42 次插入4 次删除
  1. 28 4
      src/Entity/ExtensionWuLiuEntity.php
  2. 14 0
      src/Extension.php

+ 28 - 4
src/Entity/ExtensionWuLiuEntity.php

@@ -3,14 +3,34 @@ declare(strict_types=1);
 
 namespace SixShop\AliyunWuliu\Entity;
 
+use SixShop\AliyunWuliu\Extension;
 use SixShop\AliyunWuliu\Facade\WuLiuClient;
+use SixShop\Core\Contracts\LogisticsInformationResponse;
+use SixShop\Core\Contracts\LogisticsInterface;
 use SixShop\Core\Entity\BaseEntity;
 use think\facade\Cache;
 use think\Model;
 use function SixShop\Core\throw_logic_exception;
 
-class ExtensionWuLiuEntity extends BaseEntity
+class ExtensionWuLiuEntity extends BaseEntity implements LogisticsInterface
 {
+    public function logisticsInformation(string $number, string $type = ''): LogisticsInformationResponse
+    {
+        $entity = $this->where('number', $number)->when($type, function (Model $query, $type) {
+            $query->where('type', $type);
+        })->findOrEmpty();
+        if (!$entity->isEmpty() && ($entity->is_sign == 1 || $entity->update_time > time() - 600)) {
+            // 已签收或10分钟内更新过,直接返回
+        } else {
+            $entity = $this->queryLogistics($number, $type, $entity);
+        }
+        return new LogisticsInformationResponse(
+            Extension::EXTENSION_ID,
+            $entity->number,
+            $entity->type,
+            $entity->toArray()
+        );
+    }
 
     public function getWuliuInfo(int $userID, string $no, string $type = ''): array
     {
@@ -29,7 +49,12 @@ class ExtensionWuLiuEntity extends BaseEntity
         if ($times > 100) {
             throw_logic_exception('查询太过频繁,请明天再试');
         }
-        $result = WuLiuClient::kdi($no, $type);
+        return $this->queryLogistics($no, $type, $entity)->toArray();
+    }
+
+    private function queryLogistics(string $number, string $type, self $entity): self
+    {
+        $result = WuLiuClient::kdi($number, $type);
         $entity->number = $result->number;
         $entity->type = $result->type;
         $entity->list = $result->list;
@@ -42,7 +67,6 @@ class ExtensionWuLiuEntity extends BaseEntity
         $entity->courier_phone = $result->courierPhone;
         $entity->take_time = $result->takeTime;
         $entity->save();
-
-        return $entity->toArray();
+        return $entity;
     }
 }

+ 14 - 0
src/Extension.php

@@ -3,13 +3,27 @@ declare(strict_types=1);
 
 namespace SixShop\AliyunWuliu;
 
+use SixShop\AliyunWuliu\Entity\ExtensionWuLiuEntity;
+use SixShop\Core\Contracts\LogisticsInterface;
 use SixShop\Core\ExtensionAbstract;
+use think\App;
 
 class Extension extends ExtensionAbstract
 {
     public const EXTENSION_ID = 'aliyun_wuliu';
+
+    public function __construct(private App $app)
+    {
+    }
+
     protected function getBaseDir(): string
     {
         return dirname(__DIR__);
     }
+
+    public function boot(): void
+    {
+        parent::boot();
+        $this->app->bind(LogisticsInterface::class, ExtensionWuLiuEntity::class);
+    }
 }