# 添加抽奖模拟功能 (Lottery Simulation)

我将实现一个抽奖模拟功能，允许管理员在后台模拟抽奖过程并分析概率分布，**全过程仅在内存中进行，不会修改数据库中的真实数据**。

## 1. API 接口设计
**接口地址**: `POST /api/admin/lottery/issues/:issue_id/simulate`

**请求参数 (Body)**:
```json
{
  "num_users": 100,      // 模拟人数
  "draws_per_user": 1    // 每人抽奖次数 (总抽奖次数 = 人数 * 次数)
}
```

**返回结果**:
```json
{
  "total_draws": 100,    // 总模拟次数
  "rewards": [
    {
      "reward_id": 1,
      "name": "IPhone 15",
      "level": 1,        // 奖品等级
      "original_qty": 10, // 初始库存
      "won_count": 2,    // 模拟中奖数
      "remaining_qty": 8,// 模拟剩余库存
      "actual_prob": 0.02,       // 实际中奖率 (2%)
      "theoretical_prob": 0.01   // 理论概率 (基于权重的 1%)
    }
  ]
}
```

## 2. 实现细节

### A. 新增处理器 `internal/api/admin/lottery_admin.go`
我将添加 `SimulateIssue` 函数，执行以下逻辑：
1.  **读取配置**: 从数据库获取指定期号 (Issue) 和奖品配置 (Reward Settings)。
2.  **内存模拟**:
    - 在内存中创建奖品库存的副本。
    - 运行加权随机算法 `N` 次（总抽奖次数）。
    - 扣减内存中的库存并记录中奖数据。
    - **关键**: 绝对不会写入数据库或修改真实库存。
3.  **统计计算**:
    - 计算每个奖品的实际中奖率与基于权重的理论概率进行对比。

### B. 注册路由 `internal/router/router.go`
- 在 `adminAuthApiRouter` 分组下添加新路由。
- `POST /lottery/issues/:issue_id/simulate` -> `adminHandler.SimulateIssue()`

## 3. 验证计划
- **功能验证**: 使用现有的活动/期号调用模拟接口，输入不同的人数和次数，验证返回的概率分布是否符合预期（例如：高权重奖品中奖率更高，库存耗尽后不再中奖）。