atendimentos.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { apiFetch, apiBaseUrl, buildAuthHeaders, refreshAccessToken, notifyAuthError } from "./client.js";
  2. export function sincronizarAtendimentos(params = {}) {
  3. return apiFetch("/api/atendimentos/sync", { method: "POST", body: params });
  4. }
  5. export function sincronizarTodosAtendimentos(params = {}) {
  6. return apiFetch("/api/atendimentos/sync-all", { method: "POST", body: params });
  7. }
  8. export function obterAtendimento(id) {
  9. return apiFetch(`/api/atendimentos/${id}`);
  10. }
  11. export function sincronizarAtendimento(id) {
  12. return apiFetch(`/api/atendimentos/${id}/sync`, { method: "POST", body: {} });
  13. }
  14. export function avaliarAtendimentosPendentes(params = {}) {
  15. return apiFetch("/api/atendimentos/avaliar", { method: "POST", body: params });
  16. }
  17. export function avaliarAtendimento(id) {
  18. return apiFetch(`/api/atendimentos/${id}/avaliar`, { method: "POST", body: {} });
  19. }
  20. export function listarAvaliacoes({ page = 1, pageSize = 20, setor, resolvido, sentimento, statusCancelamento, scoreMax, busca, ordenacao, dataInicio, dataFim } = {}) {
  21. const query = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });
  22. if (setor) query.set("setor", setor);
  23. if (resolvido) query.set("resolvido", resolvido);
  24. if (sentimento) query.set("sentimento", sentimento);
  25. if (statusCancelamento) query.set("statusCancelamento", statusCancelamento);
  26. if (scoreMax !== undefined) query.set("scoreMax", String(scoreMax));
  27. if (busca) query.set("busca", busca);
  28. if (ordenacao === "asc") query.set("ordenacao", ordenacao);
  29. if (dataInicio) query.set("dataInicio", dataInicio);
  30. if (dataFim) query.set("dataFim", dataFim);
  31. return apiFetch(`/api/atendimentos/avaliacoes?${query.toString()}`);
  32. }
  33. export function estatisticasAvaliacoes({ setor, resolvido, sentimento, statusCancelamento, busca, dataInicio, dataFim } = {}) {
  34. const query = new URLSearchParams();
  35. if (setor) query.set("setor", setor);
  36. if (resolvido) query.set("resolvido", resolvido);
  37. if (sentimento) query.set("sentimento", sentimento);
  38. if (statusCancelamento) query.set("statusCancelamento", statusCancelamento);
  39. if (busca) query.set("busca", busca);
  40. if (dataInicio) query.set("dataInicio", dataInicio);
  41. if (dataFim) query.set("dataFim", dataFim);
  42. const qs = query.toString();
  43. return apiFetch(`/api/atendimentos/avaliacoes/estatisticas${qs ? `?${qs}` : ""}`);
  44. }
  45. export function listarSetoresAvaliacoes() {
  46. return apiFetch("/api/atendimentos/avaliacoes/setores");
  47. }
  48. export function listarGoldenSet({ status, setor } = {}) {
  49. const query = new URLSearchParams();
  50. if (status) query.set("status", status);
  51. if (setor) query.set("setor", setor);
  52. const qs = query.toString();
  53. return apiFetch(`/api/atendimentos/golden-set${qs ? `?${qs}` : ""}`);
  54. }
  55. export function salvarGoldenLabel(id, dados) {
  56. return apiFetch(`/api/atendimentos/${id}/golden-label`, { method: "PATCH", body: dados });
  57. }
  58. export function aceitarGoldenLabelComoIa(id) {
  59. return apiFetch(`/api/atendimentos/${id}/golden-label/aceitar`, { method: "POST" });
  60. }
  61. export async function baixarRelatorioNaoResolvidos({ setor, sentimento, busca, ordenacao, dataInicio, dataFim } = {}) {
  62. const query = new URLSearchParams();
  63. if (setor) query.set("setor", setor);
  64. if (sentimento) query.set("sentimento", sentimento);
  65. if (busca) query.set("busca", busca);
  66. if (ordenacao === "asc") query.set("ordenacao", ordenacao);
  67. if (dataInicio) query.set("dataInicio", dataInicio);
  68. if (dataFim) query.set("dataFim", dataFim);
  69. const reqUrl = `${apiBaseUrl}/api/atendimentos/avaliacoes/relatorio?${query.toString()}`;
  70. let res;
  71. try {
  72. res = await fetch(reqUrl, { headers: buildAuthHeaders() });
  73. } catch {
  74. throw new Error("network_error");
  75. }
  76. if (res.status === 401) {
  77. try {
  78. await refreshAccessToken();
  79. } catch {
  80. notifyAuthError();
  81. throw new Error("session_expired");
  82. }
  83. try {
  84. res = await fetch(reqUrl, { headers: buildAuthHeaders() });
  85. } catch {
  86. throw new Error("network_error");
  87. }
  88. }
  89. if (res.status === 401) {
  90. notifyAuthError();
  91. throw new Error("session_expired");
  92. }
  93. if (!res.ok) {
  94. const text = await res.text().catch(() => "");
  95. let payload = null;
  96. try { payload = JSON.parse(text); } catch {}
  97. if (payload?.error === "relatorio_muito_grande") {
  98. throw new Error(`Muitos atendimentos para gerar o relatório (limite: ${payload.limite}). ${payload.dica ?? "Estreite o período ou os filtros."}`);
  99. }
  100. throw new Error(payload?.error || text || `http_error:${res.status}`);
  101. }
  102. const blob = await res.blob();
  103. const url = URL.createObjectURL(blob);
  104. const a = document.createElement("a");
  105. a.href = url;
  106. a.download = `atendimentos-nao-resolvidos-${new Date().toISOString().slice(0, 10)}.pdf`;
  107. document.body.appendChild(a);
  108. a.click();
  109. a.remove();
  110. URL.revokeObjectURL(url);
  111. }