|
|
@@ -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;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|