prepare("SELECT value, COUNT(*) AS cnt FROM redemption_codes WHERE status = 1 AND (expired_at IS NULL OR expired_at > NOW()) AND product_id = ? GROUP BY value ORDER BY value ASC"); $stmt->execute([$pid]); $valueOptions = $stmt->fetchAll(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!verifyCsrf($_POST['csrf_token'] ?? '')) { die('CSRF token无效'); } $codeValue = trim($_POST['code_value'] ?? ''); $quantity = max(1, min(100, (int)($_POST['quantity'] ?? 1))); // 校验面值是否有效 $validValues = array_map(fn($v) => $v['value'], $valueOptions); if (!in_array($codeValue, $validValues, true)) { $msg = '
无效的面值
'; } else { // 检查当前用户未使用兑换码数量 $stmt = $pdo->prepare("SELECT COUNT(*) FROM claim_records WHERE user_id = ? AND product_id = ? AND status = 1"); $stmt->execute([getCurrentUserId(), $pid]); $unusedCount = (int)$stmt->fetchColumn(); if ($unusedCount >= 200) { $msg = '
您当前未使用的兑换码已达 ' . $unusedCount . ' 条(上限200条),请先使用后再领取
'; } else { // 检查频繁领取(同面值距上一次领取不足3天) $stmt = $pdo->prepare("SELECT MAX(claimed_at) FROM claim_records WHERE user_id = ? AND product_id = ? AND value = ?"); $stmt->execute([getCurrentUserId(), $pid, $codeValue]); $lastClaim = $stmt->fetchColumn(); if ($lastClaim && strtotime($lastClaim) > strtotime('-3 days')) { $remaining = ceil((strtotime($lastClaim) + 3 * 86400 - time()) / 3600); $msg = '
当前面值兑换码距上次领取不足3天,请 ' . $remaining . ' 小时后再领取
'; } else { $pdo->beginTransaction(); try { // 查找指定面值的可领取兑换码 $stmt = $pdo->prepare('SELECT * FROM redemption_codes WHERE value = ? AND status = 1 AND (expired_at IS NULL OR expired_at > NOW()) AND product_id = ? ORDER BY id ASC LIMIT ? FOR UPDATE'); $stmt->execute([$codeValue, $pid, $quantity]); $available = $stmt->fetchAll(); if (count($available) < $quantity) { $msg = '
该面值的可领取兑换码不足,当前仅有 ' . count($available) . ' 个可用
'; $pdo->rollBack(); } else { $claimed = 0; foreach ($available as $code) { $stmt = $pdo->prepare('UPDATE redemption_codes SET status = 2, claim_user_id = ?, claimed_at = NOW() WHERE id = ?'); $stmt->execute([getCurrentUserId(), $code['id']]); $stmt = $pdo->prepare('INSERT INTO claim_records (product_id, created_at, user_id, code_name, batch_no, code_type, code, value, status, expired_at, price_tier1, price_tier2, claim_user, claimed_at) VALUES (?, NOW(), ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, NOW())'); $stmt->execute([ $code['product_id'], getCurrentUserId(), $code['name'], $code['batch_no'], $code['type'], $code['code'], $code['value'], $code['expired_at'], $code['price_tier1'], $code['price_tier2'], getCurrentUsername() ]); $claimed++; } $pdo->commit(); $_SESSION['flash_msg'] = '成功领取 ' . $claimed . ' 个兑换码!'; $_SESSION['flash_type'] = 'success'; redirect('claim_code.php'); } } catch (Exception $e) { $pdo->rollBack(); $msg = '
领取失败,请重试
'; } } } } } $totalAvailable = array_sum(array_column($valueOptions, 'cnt')); ?>

兑换码领取

当前共计可领取: 个,单次最多100个