table = \AKSRT\Core\DBMigrator::table('vip_membership_event'); } /** @param array $event */ public function begin(array $event): string|\WP_Error { global $wpdb; if ($this->table === '') { return new \WP_Error('aksrt_vip_audit_unavailable', __('会员变更审计表不可用。', 'aksrt')); } $uuid = wp_generate_uuid4(); $inserted = $wpdb->insert($this->table, [ 'event_uuid' => $uuid, 'batch_uuid' => sanitize_text_field((string) ($event['batch_uuid'] ?? '')), 'user_id' => (int) ($event['user_id'] ?? 0), 'actor_user_id' => !empty($event['actor_user_id']) ? (int) $event['actor_user_id'] : null, 'operation' => sanitize_key((string) ($event['operation'] ?? '')), 'source' => sanitize_key((string) ($event['source'] ?? 'admin')), 'reason' => sanitize_text_field((string) ($event['reason'] ?? '')), 'request_json' => wp_json_encode((array) ($event['request'] ?? [])), 'before_json' => wp_json_encode((array) ($event['before'] ?? [])), 'status' => 'pending', 'created_at' => current_time('mysql', true), ]); return $inserted === 1 ? $uuid : new \WP_Error('aksrt_vip_audit_begin_failed', __('无法创建会员变更审计记录。', 'aksrt')); } /** @param array $after */ public function complete(string $uuid, string $status, array $after = [], string $error_code = '', string $error_message = ''): bool { global $wpdb; return $wpdb->update($this->table, [ 'status' => in_array($status, ['succeeded', 'failed'], true) ? $status : 'failed', 'after_json' => wp_json_encode($after), 'error_code' => sanitize_key($error_code), 'error_message' => sanitize_text_field($error_message), 'completed_at' => current_time('mysql', true), ], ['event_uuid' => $uuid]) !== false; } /** @return array{items:array>,total:int,pages:int} */ public function query(int $page, int $per_page): array { global $wpdb; if ($this->table === '') { return ['items' => [], 'total' => 0, 'pages' => 1]; } $total = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$this->table}"); $items = $wpdb->get_results($wpdb->prepare( "SELECT e.*, u.display_name, u.user_login, a.display_name AS actor_name FROM {$this->table} e LEFT JOIN {$wpdb->users} u ON u.ID = e.user_id LEFT JOIN {$wpdb->users} a ON a.ID = e.actor_user_id ORDER BY e.id DESC LIMIT %d OFFSET %d", $per_page, max(0, $page - 1) * $per_page ), ARRAY_A); return ['items' => is_array($items) ? $items : [], 'total' => $total, 'pages' => max(1, (int) ceil(max(1, $total) / $per_page))]; } }