-- 02159 抽奖活动 Stage 2(人工奖领奖工单) -- -- 新建 `lottery_claim` 表:承载 crypto / physical / manual_other 三类人工奖 -- 从"抽中"到"运营打款/发货"的完整工单状态机。 -- -- 幂等设计:`CREATE TABLE IF NOT EXISTS`;一个 draw_id 只能有一条 claim 行 -- (UNIQUE 约束保证 POST /draw 事务不会重复挂单,避免用户端重放时重复入队)。 -- -- 关键索引: -- 1) UNIQUE (draw_id) — 抽奖记录 ↔ 领奖工单 一对一 -- 2) (activity_id, status) — 后台工单列表按活动 + 状态过滤 -- 3) (user_id, activity_id) — GET /records 按用户拉工单 -- 4) (status, expires_at) — 过期定时任务扫描 -- -- 状态机(详细见 doc/lottery-stage2 或 issue HIF-4): -- pending_claim ─── 用户提交 ──→ reviewing -- └── 超时 ──→ expired -- reviewing ─── 运营 approve ──→ paying -- └── 运营 reject ──→ rejected(用户可再次提交) -- paying ─── 运营 mark-paid ──→ paid(终态) -- └── 运营 reject ──→ rejected -- rejected ─── 用户再提交 ──→ reviewing CREATE TABLE IF NOT EXISTS `lottery_claim` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `draw_id` BIGINT UNSIGNED NOT NULL COMMENT '抽奖记录 ID', `user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户 ID', `activity_id` BIGINT UNSIGNED NOT NULL COMMENT '活动 ID', `prize_type` VARCHAR(32) NOT NULL COMMENT '奖品类型(crypto/physical/manual_other,冗余便于后台按类型过滤)', `claim_data` JSON COMMENT '用户提交的领奖表单数据(结构随 prize_type 变化)', `status` VARCHAR(32) NOT NULL DEFAULT 'pending_claim' COMMENT '状态:pending_claim / reviewing / paying / paid / rejected / expired', `submitted_at` DATETIME DEFAULT NULL COMMENT '用户提交领奖信息时间(首次提交后写;重新提交会覆盖)', `expires_at` DATETIME NOT NULL COMMENT '领奖窗口截止时间(默认 now+7d,可被奖品 config.claim_ttl_hours 覆盖)', `reviewed_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '最近一次审核操作者 user.id', `reviewed_at` DATETIME DEFAULT NULL COMMENT '最近一次审核时间', `reject_reason` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '拒绝原因', `tx_hash` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '链上交易哈希(crypto 打款)', `delivery_ref` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '快递单号 / 发货单据编号(physical 发货)', `paid_at` DATETIME DEFAULT NULL COMMENT '运营标记打款/发货完成时间', `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_draw_id` (`draw_id`), KEY `idx_activity_status` (`activity_id`, `status`), KEY `idx_user_activity` (`user_id`, `activity_id`), KEY `idx_status_expires` (`status`, `expires_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='抽奖人工奖领奖工单';