fix(cliente): exibir qrcode e acoes de whatsapp apenas apos aprovacao da conexao
This commit is contained in:
@@ -457,7 +457,7 @@ public final class ClienteHandlers implements HttpHandler {
|
||||
}
|
||||
private boolean adminEmpresa(String cargo){return "admin_empresa".equals(cargo);}
|
||||
|
||||
private void conectarEvolution(HttpExchange ex,long empresaId)throws Exception{Map<String,String>b=body(ex);String url=b.getOrDefault("instance_url","");String numero=EvolutionApiClient.onlyDigits(req(b,"numero_whatsapp"));if(numero.length()<10){HttpResponses.json(ex,400,Map.of("erro","numero_whatsapp_invalido","mensagem","Informe o número com DDD e código do país."));return;}try(Connection m=masterDs.getMasterConnection()){liberarCadastrosEvolutionOrfaos(m,numero);Map<String,Object> existente=one(m,"SELECT id,empresa_id,status FROM evolution_instancias WHERE numero_whatsapp=? ORDER BY id DESC LIMIT 1",Arrays.asList(numero));if(existente!=null){HttpResponses.json(ex,409,Map.of("erro","numero_whatsapp_ja_cadastrado","mensagem","Este número de WhatsApp já está cadastrado em uma conexão."));return;}}String instance="empresa"+empresaId+"_"+System.currentTimeMillis();String token=UUID.randomUUID().toString().replace("-","");var criada=evolutionApiClient.criarInstancia(url,instance,token,numero);try(Connection m=masterDs.getMasterConnection();PreparedStatement ps=m.prepareStatement("INSERT INTO evolution_instancias (empresa_id,instance_url,instance_token_enc,numero_whatsapp,status) VALUES (?,?,?,?, 'pendente') RETURNING id")){ps.setLong(1,empresaId);ps.setString(2,url);ps.setString(3,criada.instanceName()+":"+criada.token());ps.setString(4,numero);try(ResultSet rs=ps.executeQuery()){rs.next();Map<String,Object> resp=new LinkedHashMap<>();resp.put("id",rs.getLong(1));resp.put("instance_name",criada.instanceName());resp.put("status","pendente");resp.put("qrcode_base64",criada.qrcodeBase64());resp.put("mock",criada.mock());HttpResponses.json(ex,201,resp);}}}
|
||||
private void conectarEvolution(HttpExchange ex,long empresaId)throws Exception{Map<String,String>b=body(ex);String url=b.getOrDefault("instance_url","");String numero=EvolutionApiClient.onlyDigits(req(b,"numero_whatsapp"));if(numero.length()<10){HttpResponses.json(ex,400,Map.of("erro","numero_whatsapp_invalido","mensagem","Informe o número com DDD e código do país."));return;}try(Connection m=masterDs.getMasterConnection()){liberarCadastrosEvolutionOrfaos(m,numero);Map<String,Object> existente=one(m,"SELECT id,empresa_id,status FROM evolution_instancias WHERE numero_whatsapp=? ORDER BY id DESC LIMIT 1",Arrays.asList(numero));if(existente!=null){HttpResponses.json(ex,409,Map.of("erro","numero_whatsapp_ja_cadastrado","mensagem","Este número de WhatsApp já está cadastrado em uma conexão."));return;}}String instance="empresa"+empresaId+"_"+System.currentTimeMillis();String token=UUID.randomUUID().toString().replace("-","");var criada=evolutionApiClient.criarInstancia(url,instance,token,numero);try(Connection m=masterDs.getMasterConnection();PreparedStatement ps=m.prepareStatement("INSERT INTO evolution_instancias (empresa_id,instance_url,instance_token_enc,numero_whatsapp,status) VALUES (?,?,?,?, 'pendente') RETURNING id")){ps.setLong(1,empresaId);ps.setString(2,url);ps.setString(3,criada.instanceName()+":"+criada.token());ps.setString(4,numero);try(ResultSet rs=ps.executeQuery()){rs.next();Map<String,Object> resp=new LinkedHashMap<>();resp.put("id",rs.getLong(1));resp.put("instance_name",criada.instanceName());resp.put("status","pendente");resp.put("mock",criada.mock());HttpResponses.json(ex,201,resp);}}}
|
||||
private void liberarCadastrosEvolutionOrfaos(Connection m,String numero)throws Exception{List<Map<String,Object>> existentes=rows(m,"SELECT id,instance_url,instance_token_enc FROM evolution_instancias WHERE numero_whatsapp=? ORDER BY id",Arrays.asList(numero));for(Map<String,Object> inst:existentes){String token=str(inst.get("instance_token_enc"));String instanceName=token.split(":",2)[0];if(instanceName.isBlank())continue;try{evolutionApiClient.estado(str(inst.get("instance_url")),instanceName);}catch(Exception err){if(!evolutionNaoEncontrada(err))throw err;try(PreparedStatement ps=m.prepareStatement("DELETE FROM evolution_instancias WHERE id=?")){ps.setLong(1,((Number)inst.get("id")).longValue());ps.executeUpdate();}}}}
|
||||
private boolean evolutionNaoEncontrada(Exception err){String msg=err.getMessage()==null?"":err.getMessage().toLowerCase(Locale.ROOT);return msg.contains("404")||msg.contains("not found")||msg.contains("instance not found")||msg.contains("nao encontrada")||msg.contains("não encontrada");}
|
||||
private void statusEvolution(HttpExchange ex,long empresaId)throws Exception{
|
||||
@@ -494,6 +494,10 @@ public final class ClienteHandlers implements HttpHandler {
|
||||
Long id=optLong(b.get("id"));
|
||||
Map<String,Object> inst=id!=null?evolutionInstanciaPorId(empresaId,id):evolutionInstancia(empresaId);
|
||||
if(inst==null){HttpResponses.json(ex,404,Map.of("erro","instancia_nao_configurada"));return;}
|
||||
if(!"aprovada".equalsIgnoreCase(str(inst.get("status")))){
|
||||
HttpResponses.json(ex,403,Map.of("erro","instancia_pendente_aprovacao","mensagem","Esta conexão está pendente de aprovação pelo administrador."));
|
||||
return;
|
||||
}
|
||||
String[] parts=String.valueOf(inst.get("instance_token_enc")).split(":",2);
|
||||
Map<String,Object> qr=evolutionApiClient.conectar(str(inst.get("instance_url")),parts[0],str(inst.get("numero_whatsapp")));
|
||||
HttpResponses.json(ex,200,qr);
|
||||
@@ -503,6 +507,10 @@ public final class ClienteHandlers implements HttpHandler {
|
||||
Long id=optLong(b.get("id"));
|
||||
Map<String,Object> inst=id!=null?evolutionInstanciaPorId(empresaId,id):evolutionInstancia(empresaId);
|
||||
if(inst==null){HttpResponses.json(ex,404,Map.of("erro","instancia_nao_configurada"));return;}
|
||||
if(!"aprovada".equalsIgnoreCase(str(inst.get("status")))){
|
||||
HttpResponses.json(ex,403,Map.of("erro","instancia_pendente_aprovacao","mensagem","Esta conexão está pendente de aprovação pelo administrador."));
|
||||
return;
|
||||
}
|
||||
String[] parts=String.valueOf(inst.get("instance_token_enc")).split(":",2);
|
||||
HttpResponses.json(ex,200,evolutionApiClient.logout(str(inst.get("instance_url")),parts[0]));
|
||||
}
|
||||
@@ -511,6 +519,10 @@ public final class ClienteHandlers implements HttpHandler {
|
||||
Long id=optLong(b.get("id"));
|
||||
Map<String,Object> inst=id!=null?evolutionInstanciaPorId(empresaId,id):evolutionInstancia(empresaId);
|
||||
if(inst==null){HttpResponses.json(ex,404,Map.of("erro","instancia_nao_configurada"));return;}
|
||||
if(!"aprovada".equalsIgnoreCase(str(inst.get("status")))){
|
||||
HttpResponses.json(ex,403,Map.of("erro","instancia_pendente_aprovacao","mensagem","Esta conexão está pendente de aprovação pelo administrador."));
|
||||
return;
|
||||
}
|
||||
String[] parts=String.valueOf(inst.get("instance_token_enc")).split(":",2);
|
||||
HttpResponses.json(ex,200,evolutionApiClient.reiniciar(str(inst.get("instance_url")),parts[0]));
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ function renderCards(list) {
|
||||
const evoState = evo.state || 'close';
|
||||
const instName = inst.instance_name || ('instancia_' + inst.id);
|
||||
const phoneFormatted = formatPhone(inst.numero_whatsapp);
|
||||
const isAprovada = String(inst.status || '').toLowerCase() === 'aprovada';
|
||||
|
||||
return `
|
||||
<article class="wa-card" data-id="${inst.id}">
|
||||
@@ -129,15 +130,19 @@ function renderCards(list) {
|
||||
<footer class="wa-card-footer">
|
||||
<span style="font-size: 12px; font-weight: 600; color: var(--muted-strong);">Ações:</span>
|
||||
<div class="table-actions">
|
||||
<button class="table-icon-btn" type="button" title="Conectar via QR Code" aria-label="Conectar via QR Code" onclick="abrirModalQr(${inst.id})">
|
||||
${Icons.qrCode}
|
||||
</button>
|
||||
<button class="table-icon-btn" type="button" title="Reconectar WhatsApp" aria-label="Reconectar WhatsApp" onclick="abrirModalReconectar(${inst.id})">
|
||||
${Icons.restart}
|
||||
</button>
|
||||
<button class="table-icon-btn danger" type="button" title="Desconectar WhatsApp" aria-label="Desconectar WhatsApp" onclick="abrirModalDesconectar(${inst.id})">
|
||||
${Icons.power}
|
||||
</button>
|
||||
${isAprovada ? `
|
||||
<button class="table-icon-btn" type="button" title="Conectar via QR Code" aria-label="Conectar via QR Code" onclick="abrirModalQr(${inst.id})">
|
||||
${Icons.qrCode}
|
||||
</button>
|
||||
<button class="table-icon-btn" type="button" title="Reconectar WhatsApp" aria-label="Reconectar WhatsApp" onclick="abrirModalReconectar(${inst.id})">
|
||||
${Icons.restart}
|
||||
</button>
|
||||
<button class="table-icon-btn danger" type="button" title="Desconectar WhatsApp" aria-label="Desconectar WhatsApp" onclick="abrirModalDesconectar(${inst.id})">
|
||||
${Icons.power}
|
||||
</button>
|
||||
` : `
|
||||
<span class="badge warn" style="font-size: 11px; padding: 4px 8px; font-weight: 600;">Aguardando aprovação</span>
|
||||
`}
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
@@ -200,6 +205,10 @@ async function requisitarQrCode() {
|
||||
function abrirModalQr(id, initialData = null) {
|
||||
selectedInstanciaId = id;
|
||||
const inst = conexoes.find(c => c.id === id);
|
||||
if (inst && String(inst.status || '').toLowerCase() !== 'aprovada') {
|
||||
Util.toast('Esta conexão ainda está pendente de aprovação pelo administrador.', true);
|
||||
return;
|
||||
}
|
||||
if (inst && inst.numero_whatsapp) {
|
||||
qrModalTitle.textContent = `Conectar ${formatPhonePlain(inst.numero_whatsapp)}`;
|
||||
} else {
|
||||
@@ -220,6 +229,11 @@ function fecharModalQr() {
|
||||
|
||||
function abrirModalReconectar(id) {
|
||||
selectedInstanciaId = id;
|
||||
const inst = conexoes.find(c => c.id === id);
|
||||
if (inst && String(inst.status || '').toLowerCase() !== 'aprovada') {
|
||||
Util.toast('Esta conexão ainda está pendente de aprovação pelo administrador.', true);
|
||||
return;
|
||||
}
|
||||
reconectarStepConfirm.classList.remove('hidden');
|
||||
reconectarStepLoading.classList.add('hidden');
|
||||
reconectarModal.classList.remove('hidden');
|
||||
@@ -251,6 +265,11 @@ async function executarReconectar() {
|
||||
|
||||
function abrirModalDesconectar(id) {
|
||||
selectedInstanciaId = id;
|
||||
const inst = conexoes.find(c => c.id === id);
|
||||
if (inst && String(inst.status || '').toLowerCase() !== 'aprovada') {
|
||||
Util.toast('Esta conexão ainda está pendente de aprovação pelo administrador.', true);
|
||||
return;
|
||||
}
|
||||
desconectarStepConfirm.classList.remove('hidden');
|
||||
desconectarStepLoading.classList.add('hidden');
|
||||
desconectarModal.classList.remove('hidden');
|
||||
@@ -286,13 +305,10 @@ form.onsubmit = async (e) => {
|
||||
try {
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
const body = Util.formData(form);
|
||||
const d = await Api.post('/api/config/evolution-instancia/conectar', body);
|
||||
await Api.post('/api/config/evolution-instancia/conectar', body);
|
||||
form.reset();
|
||||
Util.toast('WhatsApp cadastrado com sucesso!');
|
||||
Util.toast('WhatsApp cadastrado com sucesso! Aguarde a aprovação do administrador para conectar via QR Code.');
|
||||
await load();
|
||||
if (d.id) {
|
||||
abrirModalQr(d.id, d);
|
||||
}
|
||||
} catch (err) {
|
||||
Util.toast(err.message, true);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user