get_var($wpdb->prepare( "SELECT id FROM {$this->table()} WHERE code = %s", $code )); if ($exists) return 0; $result = $wpdb->insert($this->table(), [ 'code' => $code, 'amount' => $amount, 'balance' => $amount, 'status' => self::STATUS_ACTIVE, 'expires_at' => $expires_at !== '' ? $expires_at : null, 'created_at' => current_time('mysql'), 'note' => $note, ]); return $result ? (int) $wpdb->insert_id : 0; } /** * 批量生成充值卡 */ public function batch_create(float $amount, int $count, int $length = 16, string $prefix = ''): array { $codes = []; for ($i = 0; $i < $count; $i++) { $code = $prefix . strtoupper(wp_generate_password($length, false)); $id = $this->create([ 'code' => $code, 'amount' => $amount, ]); if ($id > 0) { $codes[] = $code; } } return $codes; } /** * 使用充值卡 */ public function redeem(string $code, int $user_id): array { global $wpdb; $code = sanitize_text_field($code); $card = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$this->table()} WHERE code = %s", $code ), ARRAY_A); if (!$card) { return ['success' => false, 'message' => '充值卡不存在']; } if ($card['status'] !== self::STATUS_ACTIVE) { return ['success' => false, 'message' => '充值卡已使用或已失效']; } if ($card['expires_at'] && strtotime($card['expires_at']) < time()) { // 标记过期 $wpdb->update($this->table(), ['status' => self::STATUS_EXPIRED], ['id' => (int) $card['id']]); return ['success' => false, 'message' => '充值卡已过期']; } $amount = (float) $card['balance']; // 更新卡状态 $wpdb->update($this->table(), [ 'status' => self::STATUS_USED, 'used_by' => $user_id, 'used_at' => current_time('mysql'), 'balance' => 0, ], ['id' => (int) $card['id']]); // 增加用户余额 if (class_exists('AKSRT_Credits')) { AKSRT_Credits::add($user_id, (int) $amount, 'charge_card', [ 'ref_type' => 'charge_card', 'ref_id' => (int) $card['id'], ]); } return [ 'success' => true, 'message' => sprintf('充值成功,已到账 %s 元', number_format($amount, 2)), 'amount' => $amount, ]; } /** * 获取充值卡列表 */ public function get_list(array $args = []): array { global $wpdb; $limit = max(1, min(100, (int) ($args['limit'] ?? 20))); $offset = max(0, (int) ($args['offset'] ?? 0)); $status = sanitize_key((string) ($args['status'] ?? '')); $where = []; $params = []; if ($status !== '') { $where[] = 'status = %s'; $params[] = $status; } $where_sql = $where ? 'WHERE ' . implode(' AND ', $where) : ''; $count_sql = "SELECT COUNT(*) FROM {$this->table()} {$where_sql}"; $total = $params ? (int) $wpdb->get_var($wpdb->prepare($count_sql, $params)) : (int) $wpdb->get_var($count_sql); $sql = "SELECT * FROM {$this->table()} {$where_sql} ORDER BY created_at DESC LIMIT %d OFFSET %d"; $params[] = $limit; $params[] = $offset; $items = $wpdb->get_results($wpdb->prepare($sql, $params), ARRAY_A); return [ 'items' => $items ?: [], 'total' => $total, 'page' => floor($offset / $limit) + 1, 'max_pages' => ceil($total / $limit), ]; } /** * 禁用充值卡 */ public function disable(int $id): bool { global $wpdb; return (bool) $wpdb->update($this->table(), [ 'status' => self::STATUS_DISABLED, ], ['id' => $id]); } /** * 获取统计 */ public function get_stats(): array { global $wpdb; $table = $this->table(); $row = $wpdb->get_row( "SELECT COUNT(*) as total, SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active, SUM(CASE WHEN status = 'used' THEN 1 ELSE 0 END) as used, SUM(amount) as total_amount, SUM(CASE WHEN status = 'used' THEN amount ELSE 0 END) as used_amount FROM {$table}", ARRAY_A ); return [ 'total' => (int) ($row['total'] ?? 0), 'active' => (int) ($row['active'] ?? 0), 'used' => (int) ($row['used'] ?? 0), 'total_amount' => (float) ($row['total_amount'] ?? 0), 'used_amount' => (float) ($row['used_amount'] ?? 0), ]; } }