Przeglądaj źródła

refactor(shipping-template):重构运费模板迁移类并增强规则计算功能

- 将迁移类继承自 Phinx\Migration\AbstractMigration
- 移除 think\migration\Migrator 和 think\migration\db\Column 的使用
- 在运费模板规则表中添加 sort 排序字段- 新增获取默认规则和特殊区域规则的方法
- 实现根据地区编码计算运费的逻辑
- 添加关联运费模板的模型关系定义- 增加检查地区是否属于特殊区域的功能
runphp 5 miesięcy temu
rodzic
commit
927d5b2464

+ 1 - 4
database/migrations/20251010100000_create_shipping_templates_table.php

@@ -1,9 +1,6 @@
 <?php
 
-use think\migration\Migrator;
-use think\migration\db\Column;
-
-class CreateShippingTemplatesTable extends Migrator
+class CreateShippingTemplatesTable extends \Phinx\Migration\AbstractMigration
 {
     public function change()
     {

+ 2 - 4
database/migrations/20251010100100_create_shipping_template_rules_table.php

@@ -1,9 +1,6 @@
 <?php
 
-use think\migration\Migrator;
-use think\migration\db\Column;
-
-class CreateShippingTemplateRulesTable extends Migrator
+class CreateShippingTemplateRulesTable extends \Phinx\Migration\AbstractMigration
 {
     public function change()
     {
@@ -14,6 +11,7 @@ class CreateShippingTemplateRulesTable extends Migrator
             ->addColumn('first_price', 'decimal', ['precision' => 10, 'scale' => 2, 'comment' => '首件/首重/首体积费用'])
             ->addColumn('next_price', 'decimal', ['precision' => 10, 'scale' => 2, 'comment' => '续件/续重/续体积费用'])
             ->addColumn('area_type', 'string', ['limit' => 20, 'comment' => '区域类型: default(默认), special(特殊区域)'])
+            ->addColumn('sort', 'integer', ['comment' => '排序', 'default' => 100])
             ->addColumn('regions', 'json', ['comment' => '地区信息(JSON格式,省级行政区划,包含地区编码和名称)', 'null' => true])
             ->addTimestamps('create_time', 'update_time')
             ->addIndex(['template_id'])

+ 64 - 0
src/Entity/ShippingTemplateRuleEntity.php

@@ -11,5 +11,69 @@ use SixShop\ShippingTemplate\Model\ShippingTemplateRuleModel;
  */
 class ShippingTemplateRuleEntity extends BaseEntity
 {
+    /**
+     * 根据模板ID获取默认规则
+     */
+    public function getDefaultRule(int $templateId): ?ShippingTemplateRuleModel
+    {
+        return $this->where('template_id', $templateId)
+            ->where('area_type', 'default')
+            ->find();
+    }
 
+    /**
+     * 根据模板ID获取特殊区域规则
+     */
+    public function getSpecialRules(int $templateId): iterable
+    {
+        return $this->where('template_id', $templateId)
+            ->where('area_type', 'special')
+            ->select();
+    }
+
+    /**
+     * 计算运费
+     */
+    public function calculateShippingFee(float $quantity, ?string $regionCode = null): float
+    {
+        // 获取模板ID
+        $templateId = $this->template_id;
+        
+        // 查找适用的规则
+        $rule = null;
+        
+        // 如果提供了地区编码,先检查是否匹配特殊区域规则
+        if ($regionCode) {
+            $specialRules = $this->getSpecialRules($templateId);
+            foreach ($specialRules as $specialRule) {
+                $regions = json_decode($specialRule->regions, true);
+                if (is_array($regions) && in_array($regionCode, $regions)) {
+                    $rule = $specialRule;
+                    break;
+                }
+            }
+        }
+        
+        // 如果没有匹配的特殊区域规则,则使用默认规则
+        if (!$rule) {
+            $rule = $this->getDefaultRule($templateId);
+        }
+        
+        // 如果没有找到任何规则,返回0
+        if (!$rule) {
+            return 0.0;
+        }
+        
+        // 计算运费
+        if ($quantity <= $rule->first) {
+            // 数量在首件/首重/首体积范围内
+            return (float)$rule->first_price;
+        } else {
+            // 超出部分按续件/续重/续体积计费
+            $excess = $quantity - $rule->first;
+            // 简化计算,实际项目中可能需要考虑向上取整等规则
+            $additionalFee = ceil($excess) * (float)$rule->next_price;
+            return (float)$rule->first_price + $additionalFee;
+        }
+    }
 }

+ 45 - 0
src/Model/ShippingTemplateRuleModel.php

@@ -31,4 +31,49 @@ class ShippingTemplateRuleModel extends Model
             ]
         ];
     }
+
+    /**
+     * 关联运费模板
+     */
+    public function template()
+    {
+        return $this->belongsTo(ShippingTemplateModel::class, 'template_id');
+    }
+
+    /**
+     * 获取默认规则
+     */
+    public static function getDefaultRule(int $templateId)
+    {
+        return self::where('template_id', $templateId)
+            ->where('area_type', ShippingTemplateAreaTypeEnum::DEFAULT)
+            ->find();
+    }
+
+    /**
+     * 获取特殊区域规则
+     */
+    public static function getSpecialRules(int $templateId)
+    {
+        return self::where('template_id', $templateId)
+            ->where('area_type', ShippingTemplateAreaTypeEnum::SPECIAL)
+            ->select();
+    }
+
+    /**
+     * 检查地区是否在特殊区域规则中
+     */
+    public static function checkRegionInSpecialRules(int $templateId, string $regionCode)
+    {
+        $specialRules = self::getSpecialRules($templateId);
+        
+        foreach ($specialRules as $rule) {
+            $regions = json_decode($rule->regions, true);
+            if (is_array($regions) && in_array($regionCode, $regions)) {
+                return $rule;
+            }
+        }
+        
+        return null;
+    }
 }