LotteryActivityService文档说明.md 20 KB

LotteryActivityService 抽奖活动服务类文档

概述

LotteryActivityService 是抽奖活动管理的专门服务类,负责处理抽奖活动的状态管理、验证、查询、创建、更新、删除等操作。该类专注于活动层面的业务逻辑,与核心抽奖逻辑分离,提供清晰的活动管理接口。

类结构

namespace app\common\Service\lottery;

class LotteryActivityService
{
    // 活动状态检查方法
    public static function isRunning(LotteryActivity $activity)
    public static function isEnded(LotteryActivity $activity)
    public static function isNotStarted(LotteryActivity $activity)
    public static function isSuspended(LotteryActivity $activity)
    public static function isCancelled(LotteryActivity $activity)
    public static function isInDrawTime(LotteryActivity $activity)
    
    // 活动查询方法
    public static function getRunningActivities()
    public static function getNotStartedActivities()
    public static function getEndedActivities()
    public static function getDisplayableActivities()
    
    // 活动验证方法
    public static function isValidStatus(LotteryActivity $activity)
    public static function isValidLotteryType(LotteryActivity $activity)
    
    // 活动信息方法
    public static function getActivityStatusDescription(LotteryActivity $activity)
    public static function canUserParticipate(LotteryActivity $activity, $userId)
    public static function getActivityStatistics(LotteryActivity $activity)
    
    // 活动管理方法
    public static function batchUpdateStatus()
    public static function createActivity($data)
    public static function updateActivity(LotteryActivity $activity, $data)
    public static function deleteActivity(LotteryActivity $activity)
    
    // 奖品查询方法
    public static function getPrizes($activityId = null, $page = 1, $pageSize = 10, $type = null)
    public static function getActivityPrizeStats($activityId)
    public static function getRunningActivityPrizes($page, $pageSize, $type)
    public static function getActivityPrizes($activityId, $page, $pageSize, $type)
}

核心方法详解

1. 活动状态检查方法

isRunning() - 检查活动是否正在进行

功能: 检查活动是否处于进行中状态。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 是否正在进行

逻辑:

  • 活动状态为 STATUS_ONGOING
  • 当前时间在活动开始和结束时间之间

使用示例:

$activity = LotteryActivity::find(1);
if (LotteryActivityService::isRunning($activity)) {
    echo "活动正在进行中";
}

isEnded() - 检查活动是否已结束

功能: 检查活动是否已结束。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 是否已结束

逻辑:

  • 活动状态为 STATUS_ENDED 或当前时间超过结束时间

isNotStarted() - 检查活动是否未开始

功能: 检查活动是否还未开始。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 是否未开始

逻辑:

  • 活动状态为 STATUS_NOT_STARTED 且当前时间未到开始时间

isSuspended() - 检查活动是否已暂停

功能: 检查活动是否已暂停。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 是否已暂停

逻辑:

  • 活动状态为 STATUS_SUSPENDED

isCancelled() - 检查活动是否已取消

功能: 检查活动是否已取消。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 是否已取消

逻辑:

  • 活动状态为 STATUS_CANCELLED

isInDrawTime() - 检查是否在抽奖时间内

功能: 检查当前时间是否在活动的抽奖时间范围内。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 是否在抽奖时间内

逻辑:

  • 如果未启用抽奖时间限制,返回 true
  • 否则检查当前时间是否在 draw_time_startdraw_time_end 之间

使用示例:

$activity = LotteryActivity::find(1);
if (LotteryActivityService::isInDrawTime($activity)) {
    echo "当前在抽奖时间内";
} else {
    echo "当前不在抽奖时间内";
}

2. 活动查询方法

getRunningActivities() - 获取正在进行的活动

功能: 获取所有正在进行的抽奖活动。

返回值: Collection 活动集合

查询条件:

  • 状态为 STATUS_ONGOING
  • 当前时间在活动时间范围内

使用示例:

$runningActivities = LotteryActivityService::getRunningActivities();
foreach ($runningActivities as $activity) {
    echo "活动名称:" . $activity->name;
}

getNotStartedActivities() - 获取未开始的活动

功能: 获取所有未开始的抽奖活动。

返回值: Collection 活动集合

查询条件:

  • 状态为 STATUS_NOT_STARTED
  • 开始时间大于当前时间

getEndedActivities() - 获取已结束的活动

功能: 获取所有已结束的抽奖活动。

返回值: Collection 活动集合

查询条件:

  • 状态为 STATUS_ENDED 或结束时间小于当前时间

getDisplayableActivities() - 获取可显示的活动

功能: 获取可显示的活动(排除逻辑状态)。

返回值: Collection 活动集合

查询条件:

  • 状态在可显示状态列表中(排除已关闭、已删除、已过期等逻辑状态)

3. 活动验证方法

isValidStatus() - 验证活动状态

功能: 验证活动状态是否有效。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 状态是否有效

验证逻辑:

  • 使用 LotteryEnum::isValidActivityStatus() 验证

isValidLotteryType() - 验证开奖方式

功能: 验证开奖方式是否有效。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 开奖方式是否有效

验证逻辑:

  • 使用 LotteryEnum::isValidLotteryType() 验证

4. 活动信息方法

getActivityStatusDescription() - 获取活动状态描述

功能: 获取活动的详细状态描述。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: string 状态描述

状态描述:

  • 已取消:活动已取消
  • 已暂停:活动已暂停
  • 已结束:活动已结束
  • 进行中:活动进行中
  • 未开始:活动未开始
  • 其他:未知状态

使用示例:

$activity = LotteryActivity::find(1);
$statusDesc = LotteryActivityService::getActivityStatusDescription($activity);
echo "活动状态:" . $statusDesc;

canUserParticipate() - 检查用户是否可以参与活动

功能: 检查用户是否可以参与指定活动。

参数:

  • $activity (LotteryActivity): 活动对象
  • $userId (int): 用户ID

返回值: bool 是否可以参与

检查内容:

  1. 活动状态检查(必须为进行中)
  2. 抽奖时间检查(必须在抽奖时间内)
  3. 用户群体限制检查(待实现)
  4. 用户参与次数限制检查(待实现)

使用示例:

$activity = LotteryActivity::find(1);
$userId = 123;
if (LotteryActivityService::canUserParticipate($activity, $userId)) {
    echo "用户可以参与活动";
} else {
    echo "用户不能参与活动";
}

getActivityStatistics() - 获取活动统计信息

功能: 获取活动的统计信息。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: array 统计信息

统计内容:

[
    'total_participants' => 100,  // 总参与人数
    'total_winners' => 20,        // 总中奖人数
    'total_prizes' => 5,          // 总奖品数量
    'total_conditions' => 3       // 总参与条件数量
]

使用示例:

$activity = LotteryActivity::find(1);
$stats = LotteryActivityService::getActivityStatistics($activity);
echo "参与人数:" . $stats['total_participants'];
echo "中奖人数:" . $stats['total_winners'];

5. 活动管理方法

batchUpdateStatus() - 批量更新活动状态

功能: 批量更新活动状态,处理过期和到期的活动。

逻辑:

  1. 将已过期的进行中活动标记为已结束
  2. 将到期的未开始活动标记为进行中

使用示例:

// 通常在定时任务中调用
LotteryActivityService::batchUpdateStatus();

createActivity() - 创建新活动

功能: 创建新的抽奖活动。

参数:

  • $data (array): 活动数据

返回值: LotteryActivity 创建的活动对象

验证内容:

  • 活动状态有效性
  • 开奖方式有效性

异常: Exception 验证失败时抛出异常

使用示例:

$activityData = [
    'name' => '新年抽奖活动',
    'status' => LotteryEnum::STATUS_NOT_STARTED,
    'lottery_type' => LotteryEnum::LOTTERY_TYPE_INSTANT,
    'start_time' => time() + 3600,
    'end_time' => time() + 86400,
    // ... 其他字段
];

try {
    $activity = LotteryActivityService::createActivity($activityData);
    echo "活动创建成功,ID:" . $activity->id;
} catch (Exception $e) {
    echo "活动创建失败:" . $e->getMessage();
}

updateActivity() - 更新活动

功能: 更新现有活动信息。

参数:

  • $activity (LotteryActivity): 活动对象
  • $data (array): 更新数据

返回值: bool 更新是否成功

验证内容:

  • 活动状态有效性(如果更新状态)
  • 开奖方式有效性(如果更新开奖方式)

异常: Exception 验证失败时抛出异常

使用示例:

$activity = LotteryActivity::find(1);
$updateData = [
    'name' => '更新后的活动名称',
    'status' => LotteryEnum::STATUS_ONGOING
];

try {
    $result = LotteryActivityService::updateActivity($activity, $updateData);
    if ($result) {
        echo "活动更新成功";
    }
} catch (Exception $e) {
    echo "活动更新失败:" . $e->getMessage();
}

deleteActivity() - 删除活动

功能: 删除抽奖活动。

参数:

  • $activity (LotteryActivity): 活动对象

返回值: bool 删除是否成功

验证内容:

  • 检查活动是否可以删除(进行中的活动不能删除)

异常: Exception 验证失败时抛出异常

使用示例:

$activity = LotteryActivity::find(1);
try {
    $result = LotteryActivityService::deleteActivity($activity);
    if ($result) {
        echo "活动删除成功";
    }
} catch (Exception $e) {
    echo "活动删除失败:" . $e->getMessage();
}

6. 奖品查询方法

getPrizes() - 获取奖品列表

功能: 获取奖品列表,支持按活动ID查询或查询进行中活动的奖品。

参数:

  • $activityId (int|null): 活动ID,不传则查询进行中活动的奖品
  • $page (int): 页码,默认1
  • $pageSize (int): 每页数量,默认10
  • $type (array|null): 奖品类型筛选数组

返回值: \think\Paginator 分页对象

返回格式:

[
    'list' => [
        [
            'id' => 1,
            'activity_id' => 1,
            'name' => '一等奖',
            'type' => 2,
            'type_text' => '实物奖品',
            'image' => '/uploads/prize1.jpg',
            'description' => '奖品描述',
            'probability' => 0.01,
            'probability_percent' => 1.00,
            'total_stock' => 10,
            'remain_stock' => 8,
            'stock_percent' => 80.00,
            'win_prompt' => '恭喜中奖!',
            'sort_order' => 1,
            'unlock_people_num' => 100,
            'is_unlocked' => true,
            'activity_name' => '新年抽奖活动',
            'activity_status' => 2,
            'createtime' => 1640995200
        ]
    ],
    'total' => 1
]

getActivityPrizeStats() - 获取活动奖品统计信息

功能: 获取指定活动的奖品统计信息。

参数:

  • $activityId (int): 活动ID

返回值: array 统计信息

返回格式:

[
    'total_prizes' => 5,           // 总奖品数量
    'total_stock' => 100,          // 总库存
    'remain_stock' => 80,          // 剩余库存
    'used_stock' => 20,            // 已使用库存
    'prize_types' => [             // 按类型统计
        2 => [
            'type' => 2,
            'type_text' => '实物奖品',
            'count' => 3,
            'total_stock' => 3,
            'remain_stock' => 2
        ]
    ],
    'unlocked_prizes' => 4,        // 已解锁奖品数量
    'locked_prizes' => 1           // 未解锁奖品数量
]

getRunningActivityPrizes() - 获取进行中活动的奖品列表

功能: 获取所有进行中活动的奖品列表。

参数:

  • $page (int): 页码,默认1
  • $pageSize (int): 每页数量,默认20
  • $type (int|array|null): 奖品类型筛选,支持单个类型或类型数组

返回值: \think\Paginator 分页对象

getActivityPrizes() - 获取指定活动的奖品列表

功能: 获取指定活动的奖品列表。

参数:

  • $activityId (int): 活动ID
  • $page (int): 页码,默认1
  • $pageSize (int): 每页数量,默认20
  • $type (int|array|null): 奖品类型筛选,支持单个类型或类型数组

返回值: \think\Paginator 分页对象

使用示例

1. 活动状态管理

// 获取所有活动状态
$activity = LotteryActivity::find(1);

if (LotteryActivityService::isRunning($activity)) {
    echo "活动正在进行中";
} elseif (LotteryActivityService::isEnded($activity)) {
    echo "活动已结束";
} elseif (LotteryActivityService::isNotStarted($activity)) {
    echo "活动未开始";
} elseif (LotteryActivityService::isSuspended($activity)) {
    echo "活动已暂停";
} elseif (LotteryActivityService::isCancelled($activity)) {
    echo "活动已取消";
}

// 获取状态描述
$statusDesc = LotteryActivityService::getActivityStatusDescription($activity);
echo "活动状态:" . $statusDesc;

2. 活动查询

// 获取正在进行的活动
$runningActivities = LotteryActivityService::getRunningActivities();
echo "正在进行的活动数量:" . $runningActivities->count();

// 获取未开始的活动
$notStartedActivities = LotteryActivityService::getNotStartedActivities();
echo "未开始的活动数量:" . $notStartedActivities->count();

// 获取已结束的活动
$endedActivities = LotteryActivityService::getEndedActivities();
echo "已结束的活动数量:" . $endedActivities->count();

// 获取可显示的活动
$displayableActivities = LotteryActivityService::getDisplayableActivities();
echo "可显示的活动数量:" . $displayableActivities->count();

3. 用户参与检查

$activity = LotteryActivity::find(1);
$userId = 123;

// 检查用户是否可以参与
if (LotteryActivityService::canUserParticipate($activity, $userId)) {
    echo "用户可以参与活动";
    
    // 检查是否在抽奖时间内
    if (LotteryActivityService::isInDrawTime($activity)) {
        echo "当前在抽奖时间内,可以抽奖";
    } else {
        echo "当前不在抽奖时间内";
    }
} else {
    echo "用户不能参与活动";
}

4. 活动统计

$activity = LotteryActivity::find(1);
$stats = LotteryActivityService::getActivityStatistics($activity);

echo "活动统计信息:\n";
echo "总参与人数:" . $stats['total_participants'] . "\n";
echo "总中奖人数:" . $stats['total_winners'] . "\n";
echo "总奖品数量:" . $stats['total_prizes'] . "\n";
echo "总参与条件数量:" . $stats['total_conditions'] . "\n";

5. 活动管理

// 创建活动
$activityData = [
    'name' => '测试抽奖活动',
    'status' => LotteryEnum::STATUS_NOT_STARTED,
    'lottery_type' => LotteryEnum::LOTTERY_TYPE_INSTANT,
    'start_time' => time() + 3600,
    'end_time' => time() + 86400,
    'user_limit_type' => LotteryEnum::USER_LIMIT_ALL,
    'person_limit_num' => 10,
    'draw_time_enable' => 0
];

try {
    $activity = LotteryActivityService::createActivity($activityData);
    echo "活动创建成功,ID:" . $activity->id;
    
    // 更新活动
    $updateData = ['name' => '更新后的活动名称'];
    $result = LotteryActivityService::updateActivity($activity, $updateData);
    if ($result) {
        echo "活动更新成功";
    }
    
    // 删除活动(如果允许)
    $result = LotteryActivityService::deleteActivity($activity);
    if ($result) {
        echo "活动删除成功";
    }
    
} catch (Exception $e) {
    echo "操作失败:" . $e->getMessage();
}

6. 批量状态更新

// 在定时任务中调用
LotteryActivityService::batchUpdateStatus();
echo "活动状态批量更新完成";

7. 奖品查询

// 获取指定活动的奖品列表
$activityId = 1;
$page = 1;
$pageSize = 20;

// 单个类型筛选
$type = 2; // 实物奖品类型
$paginate = LotteryActivityService::getActivityPrizes($activityId, $page, $pageSize, $type);

// 多个类型筛选
$types = [2, 3, 4]; // 实物奖品、积分、余额
$paginate = LotteryActivityService::getActivityPrizes($activityId, $page, $pageSize, $types);

echo "奖品数量:" . $paginate->total();
echo "当前页:" . $paginate->currentPage();
echo "总页数:" . $paginate->lastPage();
foreach ($paginate->items() as $prize) {
    echo "奖品名称:" . $prize->name;
    echo "中奖率:" . $prize->probability_percent . "%";
    echo "库存百分比:" . $prize->stock_percent . "%";
}

// 获取进行中活动的奖品列表
$paginate = LotteryActivityService::getRunningActivityPrizes($page, $pageSize, $types);
echo "进行中活动奖品数量:" . $paginate->total();

// 获取活动奖品统计信息
$stats = LotteryActivityService::getActivityPrizeStats($activityId);
echo "总奖品数量:" . $stats['total_prizes'];
echo "总库存:" . $stats['total_stock'];
echo "剩余库存:" . $stats['remain_stock'];
echo "已使用库存:" . $stats['used_stock'];
echo "已解锁奖品:" . $stats['unlocked_prizes'];
echo "未解锁奖品:" . $stats['locked_prizes'];

// 按奖品类型统计
foreach ($stats['prize_types'] as $typeInfo) {
    echo "奖品类型:" . $typeInfo['type_text'];
    echo "数量:" . $typeInfo['count'];
    echo "库存:" . $typeInfo['total_stock'];
    echo "剩余:" . $typeInfo['remain_stock'];
}

注意事项

1. 状态管理

  • 活动状态变更需要谨慎处理
  • 进行中的活动不能删除
  • 状态更新需要考虑时间因素

2. 时间处理

  • 所有时间比较都基于时间戳
  • 抽奖时间限制需要考虑时区
  • 批量更新状态时需要考虑性能

3. 数据验证

  • 创建和更新活动时必须验证数据有效性
  • 使用枚举类确保状态和类型的一致性
  • 异常处理要提供友好的错误信息

4. 性能优化

  • 查询方法可以使用缓存
  • 批量操作时考虑数据库性能
  • 统计查询可以使用索引优化

5. 扩展性

  • 预留用户群体限制检查接口
  • 预留参与次数限制检查接口
  • 支持自定义验证规则

错误处理

常见异常

  1. 无效的活动状态 - 状态验证失败
  2. 无效的开奖方式 - 开奖方式验证失败
  3. 进行中的活动不能删除 - 删除验证失败

异常处理建议

  • 在控制器层捕获异常
  • 记录详细的错误日志
  • 提供用户友好的错误提示

性能优化建议

1. 缓存优化

  • 缓存活动状态信息
  • 缓存活动统计信息
  • 使用Redis缓存热点数据

2. 数据库优化

  • 为状态和时间字段添加索引
  • 优化查询条件
  • 使用批量操作减少数据库访问

3. 查询优化

  • 减少不必要的字段查询
  • 使用延迟加载
  • 优化关联查询

扩展建议

1. 活动类型扩展

  • 支持更多活动类型
  • 支持活动模板
  • 支持活动复制

2. 状态管理扩展

  • 支持状态流转日志
  • 支持状态变更通知
  • 支持状态回滚

3. 统计功能扩展

  • 支持实时统计
  • 支持多维度统计
  • 支持统计报表导出

4. 权限控制扩展

  • 支持活动权限管理
  • 支持操作权限控制
  • 支持数据权限控制

相关依赖

  • app\common\model\lottery\LotteryActivity: 活动模型
  • app\common\model\lottery\LotteryPrize: 奖品模型
  • app\common\Enum\LotteryEnum: 抽奖枚举类
  • think\Paginator: ThinkPHP分页类

版本信息

  • 创建时间: 2024年
  • 最后更新: 2024年
  • 版本: 1.0