## 痛点定位
- 新用户接口在单次请求内对每个用户做多次单表查询（资产、道具卡、优惠券、称号、最后在线时间），形成 N+1 查询，延迟随列表大小线性增加（`internal/api/admin/dashboard_admin.go` 的 `DashboardNewUsers()`）。
- 实时抽奖动态接口对每条抽奖日志逐条联查用户/期/活动/奖品，亦为 N+1 查询（`DashboardDrawStream()`）。

## 后端优化方案
- 批量聚合替代逐条查询（NewUsers）
  - 第一步：一次查出当前页的 `user_id` 列表
  - 第二步：分别对各表做分组聚合（单次查询）：
    - 资产：`SELECT user_id, COUNT(*) FROM user_inventory WHERE user_id IN (...) GROUP BY user_id`
    - 道具卡：`SELECT user_id, COUNT(*) FROM user_item_cards WHERE status=1 AND user_id IN (...) GROUP BY user_id`
    - 优惠券：`SELECT user_id, COUNT(*) FROM user_coupons WHERE user_id IN (...) GROUP BY user_id`
    - 称号：`SELECT ut.user_id, st.id, st.name FROM user_titles ut LEFT JOIN system_titles st ON st.id=ut.title_id WHERE ut.user_id IN (...)`
    - 最后在线：分别取各行为表 `MAX(time)` 按 `user_id` 聚合，再在内存求最大值
    - 积分余额：改为批量查 `user_points` 有效积分 `GROUP BY user_id`，或接入预聚合表（见下）
  - 第三步：用 `map[user_id]value` 合并到用户列表，避免每行多次往返数据库
- 连接查询替代逐条补全（DrawStream）
  - 单条 SQL 联查：`activity_draw_logs` LEFT JOIN `users`、`activity_issues`、`activities`、`activity_reward_settings`，一次性返回 `nickname/activityName/issueNumber/prizeName`
  - 保留 `since_id + limit` 增量拉取；避免循环内 `First()` 调用
- 预聚合与缓存
  - 建议增加 `user_stats` 表（或 Redis 缓存）维护：`points_balance`、`inventory_count`、`item_card_count`、`coupon_count`、`title_list`、`last_online_at`
    - 更新策略：
      - 同步：在相关写入路径（发放积分/道具卡/优惠券/称号、抽奖、下单）更新统计
      - 异步：crontab 每 1-5 分钟增量刷新
  - 实时抽奖：为最近 50 条结果加 3-5 秒内存缓存（LRU 或 Redis）
- 限流与分页
  - 新用户默认 `page_size=20`，最大 50；实时抽奖 `limit<=100`
  - 对于“今年”范围下分页检索控制页大小，避免一次返回过多用户

## 数据库与索引
- 新建/确认索引：
  - `users(created_at)`、`users(id)`
  - `activity_draw_logs(id DESC, user_id, issue_id, reward_id, created_at)`
  - `user_inventory(user_id)`、`user_item_cards(user_id,status)`、`user_coupons(user_id)`、`user_titles(user_id,title_id)`
  - `user_points(user_id, valid_end)`、`user_points_ledger(user_id, created_at)`
- 可选：为 `log_request(path, created_at)` 增加 `user_id` 字段与索引，精确“最后在线时间”

## 前端协同优化
- 新用户页签切换时：防抖 200ms；保留上次结果并显示加载骨架，避免空白闪烁
- 实时抽奖轮询：保持 5s；追加条目后裁剪到 100-200 条以保证 DOM 轻量；使用 `ref` 持有列表（已改）
- 宽度问题：动态项允许换行并分两行展示（已改），避免不可见

## 验收指标
- 新用户接口：在 `page_size=20` 时 P95 响应时间 < 200ms（本地数据量下）
- 实时抽奖接口：在 `limit=50` 时 P95 响应时间 < 150ms；每轮轮询端到端显示时间 < 300ms

## 下一步实现内容（获批后执行）
1) 重写 `DashboardNewUsers()` 为批量聚合与合并映射
2) 重写 `DashboardDrawStream()` 为单次 LEFT JOIN 联查
3) 添加必要索引迁移脚本
4) 可选：落地 `user_stats` 预聚合与写路径刷新机制

确认后我将按上述方案逐条落地并提供压测数据与对比报告。