You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不修改核心类扩展Botble ShippingStatusEnum添加新常量

问题:扩展Laravel电商系统的配送状态枚举(不修改核心文件)

我正在为基于Laravel的电商系统开发自定义插件,系统使用核心类ShippingStatusEnum管理配送状态。需要添加新状态in_transit(运输中),但不能修改原始核心枚举文件。

尝试创建了扩展类,但调用ShippingStatusEnum时新状态不显示。

自己编写的扩展类代码:

namespace Botble\OrderManagement\Enums;

use Botble\Ecommerce\Enums\ShippingStatusEnum;
use Botble\Base\Facades\BaseHelper;
use Illuminate\Support\HtmlString;

class ExtendedShippingStatusEnum extends ShippingStatusEnum
{
    public const IN_TRANSIT = 'in_transit';

    public function toHtml(): HtmlString|string
    {
        $color = match ($this->value) {
            self::IN_TRANSIT => 'primary',
            default => parent::toHtml(),
        };

        return BaseHelper::renderBadge($this->label(), $color);
    }
}

核心ShippingStatusEnum.php代码:

<?php

namespace Botble\Ecommerce\Enums;

use Botble\Base\Facades\BaseHelper;
use Botble\Base\Supports\Enum;
use Illuminate\Support\HtmlString;

class ShippingStatusEnum extends Enum
{
   public const NOT_APPROVED = 'not_approved';
   public const APPROVED = 'approved';
   public const PENDING = 'pending';
   public const ARRANGE_SHIPMENT = 'arrange_shipment';
   public const READY_TO_BE_SHIPPED_OUT = 'ready_to_be_shipped_out';
   public const PICKING = 'picking';
   public const DELAY_PICKING = 'delay_picking';
   public const PICKED = 'picked';
   public const NOT_PICKED = 'not_picked';
   public const DELIVERING = 'delivering';
   public const DELIVERED = 'delivered';
   public const NOT_DELIVERED = 'not_delivered';
   public const AUDITED = 'audited';
   public const CANCELED = 'canceled';

   public static $langPath = 'plugins/ecommerce::shipping.statuses';

   public function toHtml(): HtmlString|string
   {
       $color = match ($this->value) {
           self::NOT_APPROVED, self::PENDING, self::DELAY_PICKING, self::APPROVED => 'warning',
           self::PICKING, self::READY_TO_BE_SHIPPED_OUT, self::DELIVERING, self::ARRANGE_SHIPMENT => 'info',
           self::NOT_PICKED, self::CANCELED, self::NOT_DELIVERED => 'danger',
           self::DELIVERED, self::AUDITED => 'success',
           default => 'primary',
       };

       return BaseHelper::renderBadge($this->label(), $color);
   }
}

解决方案

1. 重写枚举静态方法,合并新状态

核心Enum基类的静态方法(如toArray()、labels())只会返回自身定义的常量,子类继承后不会自动合并新增常量。需要在扩展类中重写这些方法:

修改ExtendedShippingStatusEnum,添加以下代码:

// 返回所有枚举值(含新状态)
public static function toArray(): array
{
    return array_merge(parent::toArray(), [
        self::IN_TRANSIT => self::IN_TRANSIT,
    ]);
}

// 返回所有状态的标签(含新状态)
public static function labels(): array
{
    return array_merge(parent::labels(), [
        self::IN_TRANSIT => __('plugins/order-management::shipping.statuses.in_transit'),
    ]);
}

2. 添加新状态的语言文件

在你的插件目录下创建语言文件,确保标签能正确显示:

  • 英文语言文件:resources/lang/en/shipping/statuses.php
<?php

return [
    'in_transit' => 'In Transit',
];
  • 中文语言文件:resources/lang/zh-CN/shipping/statuses.php
<?php

return [
    'in_transit' => '运输中',
];

3. 让系统使用扩展后的枚举类

系统默认调用核心ShippingStatusEnum,需要通过以下方式替换:

方式一:全局替换(服务容器绑定)

在插件的boot()方法中添加绑定逻辑,让系统全局使用你的扩展类:

use Botble\Ecommerce\Enums\ShippingStatusEnum;
use Botble\OrderManagement\Enums\ExtendedShippingStatusEnum;

public function boot()
{
    $this->app->bind(ShippingStatusEnum::class, function () {
        return ExtendedShippingStatusEnum::class;
    });
}

方式二:局部替换

在你自己的插件代码中,直接使用ExtendedShippingStatusEnum代替核心类,比如:

use Botble\OrderManagement\Enums\ExtendedShippingStatusEnum;

// 获取所有配送状态
$allStatuses = ExtendedShippingStatusEnum::labels();

// 创建新状态实例
$inTransitStatus = ExtendedShippingStatusEnum::from('in_transit');

4. 修复toHtml()方法的逻辑错误

原扩展类的toHtml()方法存在逻辑问题:默认分支直接返回parent::toHtml(),会导致重复渲染徽章。正确写法是复用父类的颜色判断逻辑,添加新状态的规则:

public function toHtml(): HtmlString|string
{
    $color = match ($this->value) {
        self::IN_TRANSIT => 'primary',
        self::NOT_APPROVED, self::PENDING, self::DELAY_PICKING, self::APPROVED => 'warning',
        self::PICKING, self::READY_TO_BE_SHIPPED_OUT, self::DELIVERING, self::ARRANGE_SHIPMENT => 'info',
        self::NOT_PICKED, self::CANCELED, self::NOT_DELIVERED => 'danger',
        self::DELIVERED, self::AUDITED => 'success',
        default => 'primary',
    };

    return BaseHelper::renderBadge($this->label(), $color);
}

5. 清除系统缓存

修改枚举后,执行以下命令清除Laravel缓存,确保新状态生效:

php artisan cache:clear
php artisan config:clear
php artisan view:clear

内容的提问来源于stack exchange,提问作者Amine Amine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:58:10