false, 'error' => 'Não autenticado.'], 401); } } function table_has_column(PDO $pdo, string $table, string $column): bool { try { $stmt = $pdo->prepare("SHOW COLUMNS FROM {$table} LIKE ?"); $stmt->execute([$column]); return (bool)$stmt->fetch(PDO::FETCH_ASSOC); } catch (Throwable $e) { return false; } } function ensure_schema(PDO $pdo): void { $pdo->exec(" CREATE TABLE IF NOT EXISTS indicadores ( id BIGINT PRIMARY KEY, eixo_id BIGINT NULL, p TEXT, u TEXT, o TEXT, i TEXT, per TEXT, ten TEXT, um TEXT, metas LONGTEXT, realizado LONGTEXT, status VARCHAR(50) DEFAULT 'Não Iniciada', financeiro_json LONGTEXT, justificativa TEXT, escopo TEXT, vinculo_ppa TEXT, riscos_json LONGTEXT, objetivos_bsc_json LONGTEXT, programas_json LONGTEXT, parceiros_json LONGTEXT, compromissos_json LONGTEXT, boas_praticas_json LONGTEXT, licoes_aprendidas_json LONGTEXT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 "); $pdo->exec(" CREATE TABLE IF NOT EXISTS reports ( id BIGINT AUTO_INCREMENT PRIMARY KEY, indicador_id BIGINT, texto TEXT, usuario VARCHAR(100), data_hora DATETIME DEFAULT CURRENT_TIMESTAMP, ano VARCHAR(10) DEFAULT 'Geral' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 "); $pdo->exec(" CREATE TABLE IF NOT EXISTS eixos ( id BIGINT AUTO_INCREMENT PRIMARY KEY, nome TEXT, descricao TEXT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 "); $pdo->exec(" CREATE TABLE IF NOT EXISTS programas ( id BIGINT AUTO_INCREMENT PRIMARY KEY, eixo_id BIGINT NOT NULL, nome VARCHAR(255) NOT NULL, descricao TEXT, status VARCHAR(50) DEFAULT 'Não Iniciado', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 "); $additionalColumns = [ 'eixo_id' => "ALTER TABLE indicadores ADD COLUMN eixo_id BIGINT NULL", 'justificativa' => "ALTER TABLE indicadores ADD COLUMN justificativa TEXT", 'escopo' => "ALTER TABLE indicadores ADD COLUMN escopo TEXT", 'vinculo_ppa' => "ALTER TABLE indicadores ADD COLUMN vinculo_ppa TEXT", 'riscos_json' => "ALTER TABLE indicadores ADD COLUMN riscos_json LONGTEXT", 'objetivos_bsc_json' => "ALTER TABLE indicadores ADD COLUMN objetivos_bsc_json LONGTEXT", 'programas_json' => "ALTER TABLE indicadores ADD COLUMN programas_json LONGTEXT", 'parceiros_json' => "ALTER TABLE indicadores ADD COLUMN parceiros_json LONGTEXT", 'compromissos_json' => "ALTER TABLE indicadores ADD COLUMN compromissos_json LONGTEXT", 'boas_praticas_json' => "ALTER TABLE indicadores ADD COLUMN boas_praticas_json LONGTEXT", 'licoes_aprendidas_json' => "ALTER TABLE indicadores ADD COLUMN licoes_aprendidas_json LONGTEXT" ]; foreach ($additionalColumns as $column => $sql) { if (!table_has_column($pdo, 'indicadores', $column)) { try { $pdo->exec($sql); } catch (Throwable $e) { } } } } function decode_json_field($value, array $default = []): array { if (!is_string($value) || trim($value) === '') { return $default; } $decoded = json_decode($value, true); return is_array($decoded) ? $decoded : $default; } function sanitize_text($value): string { return trim((string)$value); } $pdo = pdo(); ensure_schema($pdo); if (isset($_GET['api'])) { require_panel_auth(); $act = (string)($_GET['api'] ?? ''); $input = json_decode(file_get_contents('php://input') ?: '', true) ?: []; try { if ($act === 'get_eixos') { $stmt = $pdo->query("SELECT * FROM eixos ORDER BY id ASC"); painel_json(['ok' => true, 'eixos' => $stmt->fetchAll(PDO::FETCH_ASSOC)]); } if ($act === 'save_eixo') { $nome = sanitize_text($input['nome'] ?? ''); $desc = sanitize_text($input['descricao'] ?? ''); if ($nome === '') { painel_json(['ok' => false, 'error' => 'Nome obrigatório.'], 400); } $stmt = $pdo->prepare("INSERT INTO eixos (nome, descricao) VALUES (?, ?)"); $stmt->execute([$nome, $desc]); painel_json(['ok' => true]); } if ($act === 'del_eixo') { $id = (int)($input['id'] ?? 0); if ($id <= 0) { painel_json(['ok' => false, 'error' => 'ID inválido.'], 400); } $stmt = $pdo->prepare("DELETE FROM eixos WHERE id = ?"); $stmt->execute([$id]); painel_json(['ok' => true]); } if ($act === 'get_programas') { $stmt = $pdo->query("SELECT * FROM programas ORDER BY id DESC"); painel_json(['ok' => true, 'programas' => $stmt->fetchAll(PDO::FETCH_ASSOC)]); } if ($act === 'save_programa') { $eixo_id = (int)($input['eixo_id'] ?? 0); $nome = sanitize_text($input['nome'] ?? ''); $descricao = sanitize_text($input['descricao'] ?? ''); $status = sanitize_text($input['status'] ?? 'Não Iniciado'); if ($eixo_id <= 0 || $nome === '') { painel_json(['ok' => false, 'error' => 'Informe eixo e nome do programa.'], 400); } $stmt = $pdo->prepare("INSERT INTO programas (eixo_id, nome, descricao, status) VALUES (?, ?, ?, ?)"); $stmt->execute([$eixo_id, $nome, $descricao, $status]); painel_json(['ok' => true]); } if ($act === 'get') { $stmt = $pdo->query("SELECT * FROM indicadores ORDER BY id DESC"); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $out = []; foreach ($rows as $r) { $r['metas'] = decode_json_field($r['metas'] ?? '{}'); $r['realizado'] = decode_json_field($r['realizado'] ?? '{}'); $r['financeiro'] = decode_json_field($r['financeiro_json'] ?? '[]'); $r['riscos'] = decode_json_field($r['riscos_json'] ?? '[]'); $r['objetivos_bsc'] = decode_json_field($r['objetivos_bsc_json'] ?? '[]'); $r['programas'] = decode_json_field($r['programas_json'] ?? '[]'); $r['parceiros'] = decode_json_field($r['parceiros_json'] ?? '[]'); $r['compromissos'] = decode_json_field($r['compromissos_json'] ?? '[]'); $r['boas_praticas'] = decode_json_field($r['boas_praticas_json'] ?? '[]'); $r['licoes_aprendidas'] = decode_json_field($r['licoes_aprendidas_json'] ?? '[]'); $out[] = $r; } painel_json(['ok' => true, 'payload' => $out]); } if ($act === 'save') { $payload = $input['payload'] ?? null; if (!is_array($payload)) { painel_json(['ok' => false, 'error' => 'Payload inválido.'], 400); } $stmt = $pdo->prepare(" INSERT INTO indicadores ( id, eixo_id, p, u, o, i, per, ten, um, metas, realizado, status, financeiro_json, justificativa, escopo, vinculo_ppa, riscos_json, objetivos_bsc_json, programas_json, parceiros_json, compromissos_json, boas_praticas_json, licoes_aprendidas_json ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE eixo_id=VALUES(eixo_id), p=VALUES(p), u=VALUES(u), o=VALUES(o), i=VALUES(i), per=VALUES(per), ten=VALUES(ten), um=VALUES(um), metas=VALUES(metas), realizado=VALUES(realizado), status=VALUES(status), financeiro_json=VALUES(financeiro_json), justificativa=VALUES(justificativa), escopo=VALUES(escopo), vinculo_ppa=VALUES(vinculo_ppa), riscos_json=VALUES(riscos_json), objetivos_bsc_json=VALUES(objetivos_bsc_json), programas_json=VALUES(programas_json), parceiros_json=VALUES(parceiros_json), compromissos_json=VALUES(compromissos_json), boas_praticas_json=VALUES(boas_praticas_json), licoes_aprendidas_json=VALUES(licoes_aprendidas_json) "); foreach ($payload as $i) { $id = (int)($i['id'] ?? 0); if ($id <= 0) continue; $stmt->execute([ $id, isset($i['eixo_id']) && $i['eixo_id'] !== '' ? (int)$i['eixo_id'] : null, sanitize_text($i['p'] ?? ''), sanitize_text($i['u'] ?? ''), sanitize_text($i['o'] ?? ''), sanitize_text($i['i'] ?? ''), sanitize_text($i['per'] ?? ''), sanitize_text($i['ten'] ?? ''), sanitize_text($i['um'] ?? ''), json_encode($i['metas'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['realizado'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), sanitize_text($i['status'] ?? 'Não Iniciada'), json_encode($i['financeiro'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), sanitize_text($i['justificativa'] ?? ''), sanitize_text($i['escopo'] ?? ''), sanitize_text($i['vinculo_ppa'] ?? ''), json_encode($i['riscos'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['objetivos_bsc'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['programas'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['parceiros'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['compromissos'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['boas_praticas'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), json_encode($i['licoes_aprendidas'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ]); } painel_json(['ok' => true]); } if ($act === 'delete') { $id = (int)($input['id'] ?? 0); if ($id <= 0) { painel_json(['ok' => false, 'error' => 'ID inválido.'], 400); } $stmt = $pdo->prepare("DELETE FROM indicadores WHERE id = ?"); $stmt->execute([$id]); $stmt = $pdo->prepare("DELETE FROM reports WHERE indicador_id = ?"); $stmt->execute([$id]); painel_json(['ok' => true]); } if ($act === 'reports') { $id = (int)($_GET['id'] ?? 0); $stmt = $pdo->prepare("SELECT * FROM reports WHERE indicador_id = ? ORDER BY data_hora DESC"); $stmt->execute([$id]); painel_json(['ok' => true, 'reports' => $stmt->fetchAll(PDO::FETCH_ASSOC)]); } if ($act === 'save_report') { $id = (int)($input['id'] ?? 0); $txt = sanitize_text($input['texto'] ?? ''); $ano = sanitize_text($input['ano'] ?? 'Geral'); if ($id <= 0 || $txt === '') { painel_json(['ok' => false, 'error' => 'Dados inválidos.'], 400); } $stmt = $pdo->prepare("INSERT INTO reports (indicador_id, texto, usuario, ano) VALUES (?, ?, ?, ?)"); $stmt->execute([$id, $txt, $_SESSION['username'] ?? 'Admin', $ano]); painel_json(['ok' => true]); } painel_json(['ok' => false, 'error' => 'Ação inválida.'], 400); } catch (Throwable $e) { error_log('Erro painel.php API: ' . $e->getMessage()); painel_json(['ok' => false, 'error' => 'Erro interno no servidor.'], 500); } } if (empty($_SESSION['auth'])) { header('Location: /api/login_test.html'); exit; } ?> SEDET 360 - Painel Estratégico
SEDET

Monitoramento PEI

Painel Estratégico

Mapa Estratégico (Clique para filtrar)

Monitoramento Geral

Total de Indicadores
0
Concluídos/Ativos0
Em Andamento0
Atenção/Início0
Paralisados/Outros0
Filtro Ativo

...

Lista Completa

Gerenciar Eixos

Novo Eixo

Novo Indicador

Metas

Planejamento e Alinhamento Estratégico (BSC)

Acompanhamento Físico-Financeiro

Lançamento de Realizado

Gestão de Riscos (ISO 31000)

Histórico