事件监听设计.md 9.2 KB

任务模块事件监听设计

1. 概述

任务模块采用事件驱动架构,通过事件机制与其他模块进行松耦合通信。本文档描述任务模块提供的核心事件以及如何监听这些事件。

2. 核心事件

任务模块提供以下核心事件:

2.1 任务完成事件 (TaskCompletedEvent)

当用户完成任务时触发此事件。

/**
 * 当任务完成时触发
 */
class TaskCompletedEvent
{
    public int $userId;        // 用户ID
    public int $taskId;        // 任务ID
    public string $taskName;   // 任务名称
    public string $taskType;   // 任务类型
    public string $completedAt; // 完成时间
    public array $rewards;     // 任务奖励内容
}

2.2 任务奖励领取事件 (TaskRewardClaimedEvent)

当用户领取任务奖励时触发此事件。

/**
 * 当用户领取任务奖励时触发
 */
class TaskRewardClaimedEvent
{
    public int $userId;        // 用户ID
    public int $taskId;        // 任务ID
    public string $taskName;   // 任务名称
    public array $rewards;     // 实际发放的奖励
    public string $claimedAt;  // 领取时间
    public bool $isSuccess;    // 奖励是否成功发放
}

3. 事件监听器设计

3.1 监听器基类

为了统一处理逻辑,我们设计一个基础监听器类:

abstract class BaseTaskEventListener
{
    /**
     * 处理事件
     *
     * @param mixed $event 事件对象
     * @return void
     */
    abstract public function handle($event): void;
    
    /**
     * 记录事件日志
     *
     * @param string $message 日志消息
     * @param array $context 上下文数据
     * @return void
     */
    protected function logEvent(string $message, array $context = []): void
    {
        Log::info($message, $context);
    }
}

3.2 任务完成事件监听器

class TaskCompletedListener extends BaseTaskEventListener
{
    protected UserService $userService;
    protected ItemService $itemService;
    
    /**
     * 构造函数
     */
    public function __construct(UserService $userService, ItemService $itemService)
    {
        $this->userService = $userService;
        $this->itemService = $itemService;
    }
    
    /**
     * 处理任务完成事件
     *
     * @param TaskCompletedEvent $event
     * @return void
     */
    public function handle($event): void
    {
        // 记录日志
        $this->logEvent("用户 {$event->userId} 完成了任务 {$event->taskName}", [
            'user_id' => $event->userId,
            'task_id' => $event->taskId,
            'task_type' => $event->taskType,
            'completed_at' => $event->completedAt
        ]);
        
        // 更新用户统计数据
        $this->userService->incrementTaskCompletionCount($event->userId, $event->taskType);
        
        // 发送通知
        $this->sendTaskCompletionNotification($event->userId, $event->taskName);
    }
    
    /**
     * 发送任务完成通知
     *
     * @param int $userId 用户ID
     * @param string $taskName 任务名称
     * @return void
     */
    private function sendTaskCompletionNotification(int $userId, string $taskName): void
    {
        // 发送通知逻辑
        // 可以调用通知模块的服务
    }
}

3.3 任务奖励领取事件监听器

class TaskRewardClaimedListener extends BaseTaskEventListener
{
    protected ItemService $itemService;
    protected TeamProfitService $teamProfitService;
    
    /**
     * 构造函数
     */
    public function __construct(ItemService $itemService, TeamProfitService $teamProfitService)
    {
        $this->itemService = $itemService;
        $this->teamProfitService = $teamProfitService;
    }
    
    /**
     * 处理任务奖励领取事件
     *
     * @param TaskRewardClaimedEvent $event
     * @return void
     */
    public function handle($event): void
    {
        // 记录日志
        $this->logEvent("用户 {$event->userId} 领取了任务 {$event->taskName} 的奖励", [
            'user_id' => $event->userId,
            'task_id' => $event->taskId,
            'rewards' => $event->rewards,
            'claimed_at' => $event->claimedAt,
            'is_success' => $event->isSuccess
        ]);
        
        // 如果奖励发放成功
        if ($event->isSuccess) {
            // 处理团队收益分成
            $this->processTeamProfit($event);
            
            // 发送奖励领取通知
            $this->sendRewardNotification($event->userId, $event->taskName, $event->rewards);
        }
    }
    
    /**
     * 处理团队收益分成
     *
     * @param TaskRewardClaimedEvent $event
     * @return void
     */
    private function processTeamProfit(TaskRewardClaimedEvent $event): void
    {
        // 遍历奖励
        foreach ($event->rewards as $reward) {
            if (isset($reward['item_id']) && isset($reward['quantity'])) {
                // 记录任务完成收益
                $this->teamProfitService->recordTaskCompleteProfit(
                    $event->userId,
                    $event->taskId,
                    $reward['item_id'],
                    $reward['quantity']
                );
            }
        }
    }
    
    /**
     * 发送奖励领取通知
     *
     * @param int $userId 用户ID
     * @param string $taskName 任务名称
     * @param array $rewards 奖励内容
     * @return void
     */
    private function sendRewardNotification(int $userId, string $taskName, array $rewards): void
    {
        // 发送通知逻辑
        // 可以调用通知模块的服务
    }
}

4. 事件注册

在任务模块的服务提供者中注册事件监听器:

// app/Module/Task/Providers/TaskServiceProvider.php
public function boot()
{
    // 注册事件监听器
    $this->app['events']->listen(
        \App\Module\Task\Events\TaskCompletedEvent::class,
        \App\Module\Task\Listeners\TaskCompletedListener::class
    );
    
    $this->app['events']->listen(
        \App\Module\Task\Events\TaskRewardClaimedEvent::class,
        \App\Module\Task\Listeners\TaskRewardClaimedListener::class
    );
}

5. 与其他模块的集成

5.1 与物品模块集成

任务奖励领取事件可以触发物品模块的相关操作:

// 在TaskRewardClaimedListener中
private function processItemRewards(TaskRewardClaimedEvent $event): void
{
    foreach ($event->rewards as $reward) {
        if (isset($reward['item_id']) && isset($reward['quantity'])) {
            // 调用物品模块服务添加物品
            $this->itemService->addItem(
                $event->userId,
                $reward['item_id'],
                $reward['quantity'],
                [
                    'source_type' => 'task_reward',
                    'source_id' => $event->taskId,
                    'details' => ['task_name' => $event->taskName]
                ]
            );
        }
    }
}

5.2 与团队模块集成

任务奖励领取事件可以触发团队收益分成:

// 在TaskRewardClaimedListener中
private function processTeamProfit(TaskRewardClaimedEvent $event): void
{
    foreach ($event->rewards as $reward) {
        if (isset($reward['item_id']) && isset($reward['quantity'])) {
            // 调用团队模块服务记录任务完成收益
            $this->teamProfitService->recordTaskCompleteProfit(
                $event->userId,
                $event->taskId,
                $reward['item_id'],
                $reward['quantity']
            );
        }
    }
}

5.3 与通知模块集成

任务完成和奖励领取事件可以触发通知发送:

// 在TaskCompletedListener中
private function sendTaskCompletionNotification(int $userId, string $taskName): void
{
    // 调用通知模块服务发送通知
    $this->notificationService->send(
        $userId,
        'task_completed',
        [
            'task_name' => $taskName,
            'message' => "恭喜您完成了任务:{$taskName}!"
        ]
    );
}

6. 事件触发

在任务服务中触发事件:

// app/Module/Task/Services/TaskService.php

/**
 * 完成任务
 *
 * @param int $userId 用户ID
 * @param int $taskId 任务ID
 * @return array 完成结果
 */
public function completeTask(int $userId, int $taskId): array
{
    // 任务完成逻辑...
    
    // 触发任务完成事件
    event(new TaskCompletedEvent(
        $userId,
        $taskId,
        $task->name,
        $task->type,
        now()->toDateTimeString(),
        json_decode($task->rewards, true)
    ));
    
    return [
        'success' => true,
        'message' => '任务完成成功',
        'task_id' => $taskId
    ];
}

/**
 * 领取任务奖励
 *
 * @param int $userId 用户ID
 * @param int $taskId 任务ID
 * @return array 领取结果
 */
public function claimTaskReward(int $userId, int $taskId): array
{
    // 奖励领取逻辑...
    
    // 触发任务奖励领取事件
    event(new TaskRewardClaimedEvent(
        $userId,
        $taskId,
        $task->name,
        $rewardsData,
        now()->toDateTimeString(),
        true
    ));
    
    return [
        'success' => true,
        'message' => '奖励领取成功',
        'rewards' => $rewardsData
    ];
}