Skip to content

⚠️ 本文基于 CRMEB 原版整理,EBAOZU 二开部分可能有差异,以实际系统为准。

CRMEB多店系统事件机制说明

概述

CRMEB多店系统基于ThinkPHP 6.0的事件机制,实现了业务逻辑的解耦。事件机制允许在特定操作发生时触发相应的监听器,执行额外的业务逻辑。


事件配置文件

事件配置位于 app/event.php 文件中:

return [
    'bind' => [],
    'listen' => [
        // 事件名称 => [监听器类列表]
        'user.register' => [\app\listener\user\Register::class],
        'order.create' => [\app\listener\order\Create::class],
        // ...
    ],
    'subscribe' => [],
];

系统事件列表

用户相关事件

事件名称监听器说明
user.registerRegister::class用户注册事件
user.cancelUserCancelUser::class用户注销事件
user.loginLogin::class用户登录事件
user.vipPayVipUser::class用户购买VIP支付成功
user.rechargeRecharge::class用户储值支付成功
user.rechargeRefundRechargeRefund::class用户储值退款成功
user.extractExtract::class用户申请提现
user.workUserBindWorkMember::class用户绑定企业微信成员
user.createCreateSuccess::class用户创建事件
user.updateUpdateSuccess::class用户更新事件
user.clientUserBindClient::class用户绑定企业微信客户
user.member.updateMemberUpdateSuccess::class会员更新事件
user.address.updateAddressUpdateSuccess::class修改用户地址事件
user.activate.levelActivateLevel::class用户激活会员卡

订单相关事件

事件名称监听器说明
cart.addAddCart::class加入购物车事件
order.createCreate::class订单创建事件
order.pricePriceRevision::class订单改价格事件
order.applyRefundApplyRefund::class订单退款申请事件
order.refuseRefundRefuseRefund::class订单拒绝退款申请事件
order.refundRefund::class订单退款事件
order.payPay::class订单支付事件
order.deliveryDelivery::class订单发货事件
order.takeTake::class订单收货事件
order.commentComment::class订单评价事件
order.cancelCancel::class订单取消删除事件
order.writeoffWriteoff::class订单核销事件
order.routine.shippingOrderShipping::class小程序发货信息事件

支付相关事件

事件名称监听器说明
pay.create.orderPayCreateOrderListener::class支付订单创建事件
pay.notifyPayNotifyListener::class支付异步回调事件
pay.mchNotifyPayMchNotifyListener::class商家转账异步回调事件
pay.scan.notifyScannedNotifyListener::class支付扫码异步回调

商品相关事件

事件名称监听器说明
product.createCreateSuccess::class商品创建事件
product.deleteDeleteSuccess::class商品删除事件
product.statusStatusSuccess::class商品状态事件
product.replyReply::class商品评价事件
product.collectCollect::class商品收藏事件
product.reply.updateReplyUpdateSuccess::class更新评论事件
product.shipping.updateShippingUpdateSuccess::class修改运费模板事件

门店/供应商事件

事件名称监听器说明
store.verifyApplyVerify::class门店入驻审核事件
store.createStoreSuccess::class创建门店事件
store.deleteDeleteSuccess::class删除门店事件
store.statusStatusSuccess::class门店状态事件
supplier.verifyApplyVerify::class供应商入驻审核事件
supplier.createSupplierSuccess::class创建供应商事件
supplier.deleteDeleteSuccess::class删除供应商事件
supplier.statusStatusSuccess::class供应商状态事件

系统事件

事件名称监听器说明
admin.loginLoginSuccess::class后台登录事件
admin.logoutLogoutSuccess::class后台退出事件
diy.updateDiyUpdateSuccess::classDIY更新事件
config.createCreateSuccess::class创建配置事件
config.deleteDeleteSuccess::class删除配置事件
config.statusStatusSuccess::class配置状态事件
notice.noticeNotice::class通知消息事件
sms.sendAfterSendAfterSuccess::class短信发送后事件
crontabSystemTimer::class定时执行事件

社区事件

事件名称监听器说明
community.operateCommunityOperate::class帖子操作事件
community.deleteCommunityDelete::class帖子删除事件
community.likeCommunityLike::class帖子点赞事件
community.comment.operateCommunityCommentOperate::class评论操作事件
community.comment.deleteCommunityCommentDelete::class评论删除事件

Swoole事件

事件名称监听器说明
swoole.initInitSwooleLockListen::classSwoole初始化事件
swoole.workerStartSwooleCronListen::classSwoole定时任务
swoole.shutDownSwooleShutdownListen::classSwoole停止事件
swoole.websocket.userUserHandler::classWebSocket用户事件
swoole.websocket.adminAdminHandler::classWebSocket后台事件
swoole.websocket.kefuKefuHandler::classWebSocket客服事件
swoole.websocket.storeStoreHandler::classWebSocket门店事件
swoole.websocket.supplierSupplierHandler::classWebSocket供应商事件
swoole.websocket.cashierCashierHandler::classWebSocket收银台事件

监听器开发规范

监听器目录结构

app/listener/
├── activity/           # 活动监听器
├── community/          # 社区监听器
├── notice/             # 通知监听器
├── order/              # 订单监听器
├── pay/                # 支付监听器
├── product/            # 商品监听器
├── sms/                # 短信监听器
├── store/              # 门店监听器
├── supplier/           # 供应商监听器
├── system/             # 系统监听器
├── user/               # 用户监听器
├── wechat/             # 微信监听器
└── work/               # 企业微信监听器

监听器基本结构

<?php
namespace app\listener\order;

use crmeb\interfaces\ListenerInterface;

/**
 * 订单创建事件监听器
 * Class Create
 * @package app\listener\order
 */
class Create implements ListenerInterface
{
    /**
     * 事件处理
     * @param $event 事件数据
     * @return void
     */
    public function handle($event): void
    {
        // 解构事件数据
        [$orderInfo, $group, $activity, $invoice_id] = $event;

        // 业务逻辑处理
        $uid = (int)($orderInfo['uid'] ?? 0);
        $oid = (int)$orderInfo['id'];

        // 调用队列任务
        OrderJob::dispatchDo('computeOrderProductTruePrice', [
            $orderInfo['uid'], 
            $orderInfo['id']
        ]);

        // 更多处理逻辑...
    }
}

监听器接口定义

<?php
namespace crmeb\interfaces;

interface ListenerInterface
{
    /**
     * 事件处理方法
     * @param mixed $event 事件数据
     * @return void
     */
    public function handle($event): void;
}

事件触发方式

使用event()助手函数

// 触发事件,传递数据
event('order.create', [$orderInfo, $group, $activity, $invoice_id]);

// 触发用户注册事件
event('user.register', [$userInfo]);

// 触发支付成功事件
event('order.pay', [$orderId, $orderInfo]);

使用Event门面类

use think\facade\Event;

// 触发事件
Event::trigger('order.create', [$orderInfo, $group, $activity, $invoice_id]);

// 监听事件(动态添加)
Event::listen('order.create', function($event) {
    // 处理逻辑
});

实战示例

示例1:创建自定义事件监听器

步骤1:创建监听器文件

<?php
// app/listener/custom/MyCustomListener.php

namespace app\listener\custom;

use crmeb\interfaces\ListenerInterface;

class MyCustomListener implements ListenerInterface
{
    public function handle($event): void
    {
        // 获取事件数据
        $data = $event[0] ?? [];

        // 业务处理
        $this->processData($data);
    }

    protected function processData($data)
    {
        // 具体业务逻辑
    }
}

步骤2:注册事件

app/event.php 中添加:

'listen' => [
    // ... 其他事件
    'my.custom.event' => [\app\listener\custom\MyCustomListener::class],
],

步骤3:触发事件

// 在需要的地方触发事件
event('my.custom.event', [$data]);

示例2:订单支付成功事件详解

<?php
namespace app\listener\order;

use app\jobs\order\OrderJob;
use app\jobs\order\OrderStatusJob;
use app\jobs\user\UserLevelJob;
use app\jobs\spread\AgentJob;
use crmeb\interfaces\ListenerInterface;

class Pay implements ListenerInterface
{
    public function handle($event): void
    {
        [$id, $orderInfo] = $event;

        // 1. 计算订单佣金
        OrderJob::dispatchDo('computeOrderBrokerage', [
            $orderInfo['uid'], 
            $orderInfo['id']
        ]);

        // 2. 写入订单支付记录
        OrderStatusJob::dispatch([
            $orderInfo['id'], 
            'pay_success', 
            [
                'change_message' => '用户付款成功', 
                'change_manager_type' => 'user'
            ]
        ]);

        // 3. 检测会员等级
        UserLevelJob::dispatch([(int)$orderInfo['uid']]);

        // 4. 处理分销等级升级
        AgentJob::dispatch([(int)$orderInfo['uid']]);

        // 5. 处理拼团逻辑
        if ($orderInfo['activity_id'] && $orderInfo['type'] == 3) {
            PinkJob::dispatchDo('createPink', [$orderInfo]);
        }
    }
}

示例3:用户注册事件

<?php
namespace app\listener\user;

use app\jobs\notice\SmsJob;
use app\jobs\user\UserJob;
use crmeb\interfaces\ListenerInterface;

class Register implements ListenerInterface
{
    public function handle($event): void
    {
        [$user] = $event;

        // 1. 发送注册短信
        SmsJob::dispatchDo('sendRegisterSms', [$user['phone']]);

        // 2. 赠送新人优惠券
        UserJob::dispatchDo('giveNewUserCoupon', [$user['uid']]);

        // 3. 处理推广关系
        if ($user['spread_uid']) {
            UserJob::dispatchDo('handleSpreadRelation', [
                $user['uid'], 
                $user['spread_uid']
            ]);
        }
    }
}

与队列任务结合

事件监听器中通常会调用队列任务来异步处理业务:

// 立即执行
OrderJob::dispatch([$orderId]);

// 指定方法执行
OrderJob::dispatchDo('methodName', [$param1, $param2]);

// 延迟执行(单位:秒)
UnpaidOrderCancelJob::dispatchSece(3600, [$orderId]);

注意事项

  1. 事件命名规范:使用 模块.操作 格式,如 order.createuser.login

  2. 监听器解耦:监听器之间应保持独立,避免相互依赖

  3. 异步处理:耗时操作应使用队列任务异步处理

  4. 异常处理:监听器中应做好异常捕获,避免影响主流程

  5. 性能考虑:一个事件可以有多个监听器,但要注意执行顺序和性能


常见问题

Q: 如何判断事件是否触发?

A: 可以在监听器中添加日志记录:

\think\facade\Log::info('event triggered', $event);

Q: 如何动态添加事件监听?

A: 使用Event门面类:

Event::listen('order.create', function($event) {
    // 动态添加的处理逻辑
});

Q: 事件监听器执行顺序是什么?

A: 按照 event.php 中配置的数组顺序依次执行

EBAOZU V4 多门店租赁商城系统文档