任务模块的事件系统是基于Laravel的事件机制实现的,用于处理任务完成、奖励领取等关键业务流程。通过事件系统,可以实现模块间的解耦,提高代码的可维护性和可扩展性。
本文档详细介绍了任务模块的事件系统设计与实现,包括事件类型、事件监听器、事件分发机制以及如何扩展事件系统。
任务模块定义了以下核心事件:
当用户完成任务时触发此事件。
事件属性:
/**
* 用户ID
* @var int
*/
public int $userId;
/**
* 任务ID
* @var int
*/
public int $taskId;
/**
* 任务名称
* @var string
*/
public string $taskName;
/**
* 任务类型
* @var string
*/
public string $taskType;
/**
* 完成时间
* @var string
*/
public string $completedAt;
/**
* 任务奖励内容
* @var array
*/
public array $rewards;
触发时机:
当用户领取任务奖励时触发此事件。
事件属性:
/**
* 用户ID
* @var int
*/
public int $userId;
/**
* 任务ID
* @var int
*/
public int $taskId;
/**
* 任务名称
* @var string
*/
public string $taskName;
/**
* 实际发放的奖励
* @var array
*/
public array $rewards;
/**
* 领取时间
* @var string
*/
public string $claimedAt;
/**
* 奖励是否成功发放
* @var bool
*/
public bool $isSuccess;
触发时机:
任务模块实现了以下事件监听器:
监听任务完成事件,执行相关操作。
主要功能:
实现示例:
/**
* 处理任务完成事件
*
* @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,
'rewards' => $event->rewards
]);
// 更新用户统计数据
// $this->updateUserTaskStats($event->userId, $event->taskType);
// 发送任务完成通知
$this->sendTaskCompletionNotification($event);
// 检查成就解锁
$this->checkAchievementUnlock($event);
}
监听任务奖励领取事件,执行相关操作。
主要功能:
实现示例:
/**
* 处理任务奖励领取事件
*
* @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->updateUserRewardStats($event->userId, $event->rewards);
// 发送奖励领取通知
$this->sendRewardClaimedNotification($event);
// 检查特殊奖励触发
$this->checkSpecialRewardTrigger($event);
} else {
// 处理奖励发放失败的情况
$this->handleRewardFailure($event);
}
}
任务模块通过TaskServiceProvider注册事件和监听器:
/**
* 应用程序的事件监听器映射
*
* @var array
*/
protected $listen = [
TaskCompletedEvent::class => [
TaskCompletedListener::class,
],
TaskRewardClaimedEvent::class => [
TaskRewardClaimedListener::class,
],
];
/**
* 引导服务
*
* @return void
*/
public function boot(): void
{
// 注册事件监听器
foreach ($this->listen as $event => $listeners) {
foreach ($listeners as $listener) {
$this->app['events']->listen($event, $listener);
}
}
}
use App\Module\Task\Events\TaskCompletedEvent;
use Illuminate\Support\Facades\Event;
// 在任务服务中分发任务完成事件
public function completeTask($userId, $taskId)
{
// 获取任务信息
$task = $this->taskRepository->find($taskId);
// 更新任务状态
$userTask = $this->userTaskRepository->getUserTask($userId, $taskId);
$userTask->status = 2; // 已完成
$userTask->completed_at = now();
$userTask->save();
// 获取任务奖励
$rewards = $this->rewardRepository->getRewardsByTaskId($taskId);
// 分发任务完成事件
Event::dispatch(new TaskCompletedEvent(
$userId,
$taskId,
$task->name,
$task->type,
now()->toDateTimeString(),
$rewards
));
return true;
}
use App\Module\Task\Events\TaskRewardClaimedEvent;
use Illuminate\Support\Facades\Event;
// 在奖励服务中分发任务奖励领取事件
public function claimReward($userId, $taskId)
{
// 获取任务信息
$task = $this->taskRepository->find($taskId);
// 获取任务奖励
$rewards = $this->rewardRepository->getRewardsByTaskId($taskId);
// 发放奖励
$isSuccess = $this->dispatchRewards($userId, $rewards);
// 更新任务状态
if ($isSuccess) {
$userTask = $this->userTaskRepository->getUserTask($userId, $taskId);
$userTask->status = 3; // 已领取奖励
$userTask->rewarded_at = now();
$userTask->save();
}
// 分发任务奖励领取事件
Event::dispatch(new TaskRewardClaimedEvent(
$userId,
$taskId,
$task->name,
$rewards,
now()->toDateTimeString(),
$isSuccess
));
return $isSuccess;
}
要添加新的事件,需要创建事件类并在TaskServiceProvider中注册:
// 创建新的事件类
namespace App\Module\Task\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class TaskResetEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* 重置类型
* @var string
*/
public string $resetType;
/**
* 重置时间
* @var string
*/
public string $resetTime;
/**
* 受影响的任务ID列表
* @var array
*/
public array $affectedTasks;
/**
* 创建一个新的事件实例
*
* @param string $resetType
* @param string $resetTime
* @param array $affectedTasks
*/
public function __construct(string $resetType, string $resetTime, array $affectedTasks)
{
$this->resetType = $resetType;
$this->resetTime = $resetTime;
$this->affectedTasks = $affectedTasks;
}
}
要添加新的监听器,需要创建监听器类并在TaskServiceProvider中注册:
// 创建新的监听器类
namespace App\Module\Task\Listeners;
use App\Module\Task\Events\TaskResetEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
class TaskResetListener extends BaseTaskEventListener implements ShouldQueue
{
/**
* 创建监听器实例
*
* @return void
*/
public function __construct()
{
//
}
/**
* 处理任务重置事件
*
* @param TaskResetEvent $event
* @return void
*/
public function handle($event): void
{
// 记录日志
$this->logEvent("任务重置:{$event->resetType}", [
'reset_type' => $event->resetType,
'reset_time' => $event->resetTime,
'affected_tasks' => $event->affectedTasks
]);
// 处理任务重置逻辑
// ...
}
}
/**
* 应用程序的事件监听器映射
*
* @var array
*/
protected $listen = [
TaskCompletedEvent::class => [
TaskCompletedListener::class,
],
TaskRewardClaimedEvent::class => [
TaskRewardClaimedListener::class,
],
TaskResetEvent::class => [
TaskResetListener::class,
],
];
可能的原因:
解决方案:
可能的原因:
解决方案:
可能的原因:
解决方案:
| 日期 | 版本 | 更新内容 |
|---|---|---|
| 2023-06-10 | 1.0 | 初始版本 |
| 2023-06-15 | 1.1 | 添加扩展事件系统章节 |
| 2023-06-20 | 1.2 | 添加常见问题与解决方案 |