ChatBot - Frontend a funcionar com Backend
This commit is contained in:
parent
e2bf3a3743
commit
cac71b22b8
@ -3,7 +3,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve --proxy-config proxy.conf.json",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
"watch": "ng build --watch --configuration development",
|
"watch": "ng build --watch --configuration development",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
|
6
ChatBot-Frontend/proxy.conf.json
Normal file
6
ChatBot-Frontend/proxy.conf.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"/api": {
|
||||||
|
"target": "http://localhost:3000",
|
||||||
|
"secure": false
|
||||||
|
}
|
||||||
|
}
|
@ -514,18 +514,15 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
.rectangle-9606a9926cc4 > svg {
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
transform: translate(0px,0px);
|
|
||||||
}
|
|
||||||
.rectangle-9606a9926cc4 {
|
.rectangle-9606a9926cc4 {
|
||||||
|
background-color:#232329;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
width: 535px;
|
width: 535px;
|
||||||
height: 588px;
|
height: 588px;
|
||||||
|
border-radius: 12px;
|
||||||
}
|
}
|
||||||
.frame {
|
.frame {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -535,30 +532,54 @@
|
|||||||
.shape.text {
|
.shape.text {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.chat-history {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
gap: 8px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 8px 0;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-history .user {
|
||||||
|
align-self: flex-end;
|
||||||
|
background: #3b4a6b;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: 18px 18px 4px 18px;
|
||||||
|
max-width: 80%;
|
||||||
|
font-size: 1rem;
|
||||||
|
box-shadow: 0 2px 8px rgba(59,74,107,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-history .bot {
|
||||||
|
align-self: flex-start;
|
||||||
|
background: #23232b;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: 18px 18px 18px 4px;
|
||||||
|
max-width: 80%;
|
||||||
|
font-size: 1rem;
|
||||||
|
box-shadow: 0 2px 8px rgba(35,35,43,0.08);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div class="group group-96e07eb27483">
|
<div class="group group-96e07eb27483">
|
||||||
<div class="shape path rectangle-9606a9926cc4">
|
<div class="shape path rectangle-9606a9926cc4">
|
||||||
<svg width="535" xmlns="http://www.w3.org/2000/svg" height="588" id="screenshot-b0f42cb3-61fe-8063-8005-9606a9926cc4" viewBox="2022 755 535 588" style="-webkit-print-color-adjust: exact" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1">
|
<div class="chat-history" #chatHistoryDiv>
|
||||||
<g id="shape-b0f42cb3-61fe-8063-8005-9606a9926cc4">
|
<div *ngFor="let msg of chatHistory" [ngClass]="msg.sender">
|
||||||
<defs></defs>
|
<span>{{ msg.text }}</span>
|
||||||
<g class="fills" id="fills-b0f42cb3-61fe-8063-8005-9606a9926cc4">
|
</div>
|
||||||
<path d="M2022.000,765.000C2022.000,759.481,2026.481,755.000,2032.000,755.000L2491.936,755.000L2547.000,755.000C2552.519,755.000,2557.000,759.481,2557.000,765.000L2557.000,1333.000C2557.000,1338.519,2552.519,1343.000,2547.000,1343.000L2032.000,1343.000C2026.481,1343.000,2022.000,1338.519,2022.000,1333.000L2022.000,765.000Z" style="fill:#1e1e22;fill-opacity:1"></path>
|
</div>
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<div class="chatbot-footer">
|
<div class="chatbot-footer">
|
||||||
<input
|
<input class="chatbot-input" type="text" [(ngModel)]="userMessage" placeholder="Digite sua mensagem..." (keyup.enter)="enviarMensagem()" />
|
||||||
class="chatbot-input"
|
<button class="chatbot-send" (click)="enviarMensagem()">
|
||||||
type="text"
|
|
||||||
placeholder="Digite sua mensagem..."
|
|
||||||
(keyup.enter)="enviarMensagem()"
|
|
||||||
/>
|
|
||||||
<button class="chatbot-send" (click)="enviarMensagem()">
|
|
||||||
<svg width="20" height="20" fill="#fff" viewBox="0 0 24 24">
|
<svg width="20" height="20" fill="#fff" viewBox="0 0 24 24">
|
||||||
<path d="M2 21l21-9-21-9v7l15 2-15 2z"/>
|
<path d="M2 21l21-9-21-9v7l15 2-15 2z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="shape text pode-falar-960a50fa2a15">
|
<div class="shape text pode-falar-960a50fa2a15">
|
||||||
|
@ -17,7 +17,6 @@ describe('AppComponent', () => {
|
|||||||
it(`should have the 'ChatBot' title`, () => {
|
it(`should have the 'ChatBot' title`, () => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.componentInstance;
|
const app = fixture.componentInstance;
|
||||||
expect(app.title).toEqual('ChatBot');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render title', () => {
|
it('should render title', () => {
|
||||||
|
@ -12,7 +12,7 @@ import { ChatService } from './chat.service';
|
|||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
userMessage = '';
|
userMessage = '';
|
||||||
resposta: string | null = null;
|
resposta: string | null = null;
|
||||||
|
chatHistory: any[] = [];
|
||||||
constructor(private chatService: ChatService) {}
|
constructor(private chatService: ChatService) {}
|
||||||
|
|
||||||
enviarMensagem() {
|
enviarMensagem() {
|
||||||
|
BIN
ChatBot-Python/__pycache__/main.cpython-313.pyc
Normal file
BIN
ChatBot-Python/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
@ -135,7 +135,7 @@ def chat_with_gpt(prompt, attempts=3):
|
|||||||
for i in range(attempts):
|
for i in range(attempts):
|
||||||
try:
|
try:
|
||||||
response = client.chat.completions.create(
|
response = client.chat.completions.create(
|
||||||
model="gpt-3.5-turbo",
|
model="gpt-3.5-turbo-0125",
|
||||||
messages=[{"role": "user", "content": prompt}],
|
messages=[{"role": "user", "content": prompt}],
|
||||||
max_tokens=300
|
max_tokens=300
|
||||||
)
|
)
|
||||||
|
6
ChatBot-Python/package-lock.json
generated
Normal file
6
ChatBot-Python/package-lock.json
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "ChatBot-Python",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
134
ChatBot-Python/server.py
Normal file
134
ChatBot-Python/server.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
from flask import Flask, request, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
from main import (
|
||||||
|
chat_with_gpt, parse_user_input, get_total_by_cunit, get_filtered_data,
|
||||||
|
get_price_comparison, compare_current_vs_previous_year, get_top_consumers,
|
||||||
|
compare_kwh_current_vs_previous_year, get_invoices_by_month_year,
|
||||||
|
get_invoices_from_inactive_units, get_total_kwh_by_building_type, get_data
|
||||||
|
)
|
||||||
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
month_map = {
|
||||||
|
"janeiro": 1, "fevereiro": 2, "março": 3, "abril": 4, "maio": 5, "junho": 6,
|
||||||
|
"julho": 7, "agosto": 8, "setembro": 9, "outubro": 10, "novembro": 11, "dezembro": 12
|
||||||
|
}
|
||||||
|
|
||||||
|
@app.route('/api/chat', methods=['POST'])
|
||||||
|
def chat():
|
||||||
|
data = request.json
|
||||||
|
user_input = data.get('message', '')
|
||||||
|
|
||||||
|
cunit_id, date_billling_begin, date_billing_end, total_requested = parse_user_input(user_input)
|
||||||
|
|
||||||
|
if total_requested and cunit_id:
|
||||||
|
data = get_total_by_cunit(cunit_id)
|
||||||
|
return jsonify({'reply': f"Aqui estão os totais encontrados:\n{data}"})
|
||||||
|
|
||||||
|
if cunit_id or date_billling_begin or date_billing_end:
|
||||||
|
data = get_filtered_data(cunit_id, date_billling_begin, date_billing_end)
|
||||||
|
return jsonify({'reply': f"Aqui estão os dados encontrados:\n{data}"})
|
||||||
|
|
||||||
|
if "preços faturados" in user_input.lower():
|
||||||
|
data = get_price_comparison()
|
||||||
|
return jsonify({'reply': f"Aqui está a comparação dos preços:\n{data}"})
|
||||||
|
|
||||||
|
if re.search(r"mês atual.*igual período.*ano anterior", user_input.lower()):
|
||||||
|
data = compare_current_vs_previous_year()
|
||||||
|
return jsonify({'reply': data})
|
||||||
|
|
||||||
|
if re.search(r"mês.*igual período.*ano anterior", user_input.lower()):
|
||||||
|
match = re.search(
|
||||||
|
r"(?:mês\s+de\s+([a-zç]+|\d{1,2}))(?:\s+do\s+ano\s+(\d{4}))?",
|
||||||
|
user_input.lower()
|
||||||
|
)
|
||||||
|
if match:
|
||||||
|
mes_input = match.group(1).strip().lower()
|
||||||
|
ano = int(match.group(2)) if match.group(2) else datetime.now().year
|
||||||
|
if mes_input.isdigit():
|
||||||
|
mes = int(mes_input)
|
||||||
|
else:
|
||||||
|
mes = month_map.get(mes_input)
|
||||||
|
if not mes:
|
||||||
|
return jsonify({'reply': "Mês não reconhecido. Tenta novamente."})
|
||||||
|
else:
|
||||||
|
mes = datetime.now().month
|
||||||
|
ano = datetime.now().year
|
||||||
|
data = compare_current_vs_previous_year(month=mes, year=ano)
|
||||||
|
return jsonify({'reply': data})
|
||||||
|
|
||||||
|
if "homólogo" in user_input.lower():
|
||||||
|
match = re.search(r"homólogo.*?(\d{4})", user_input.lower())
|
||||||
|
ano = int(match.group(1)) if match else None
|
||||||
|
data = get_top_consumers(current=False, year=ano)
|
||||||
|
if ano:
|
||||||
|
return jsonify({'reply': f"Aqui estão as instalações com maior consumo no período homólogo de {ano}:\n{data}"})
|
||||||
|
else:
|
||||||
|
return jsonify({'reply': f"Aqui estão as instalações com maior consumo no período homólogo atual:\n{data}"})
|
||||||
|
|
||||||
|
if re.search(r"total de kwh.*mês.*ano anterior", user_input.lower()):
|
||||||
|
match = re.search(
|
||||||
|
r"(?:mês\s+de\s+([a-zç]+|\d{1,2}))(?:\s+do\s+ano\s+(\d{4}))?",
|
||||||
|
user_input.lower()
|
||||||
|
)
|
||||||
|
if match:
|
||||||
|
mes_input = match.group(1).strip().lower()
|
||||||
|
ano = int(match.group(2)) if match.group(2) else datetime.now().year
|
||||||
|
if mes_input.isdigit():
|
||||||
|
mes = int(mes_input)
|
||||||
|
else:
|
||||||
|
mes = month_map.get(mes_input)
|
||||||
|
if not mes:
|
||||||
|
return jsonify({'reply': "Mês não reconhecido. Tenta novamente."})
|
||||||
|
else:
|
||||||
|
mes = datetime.now().month
|
||||||
|
ano = datetime.now().year
|
||||||
|
data = compare_kwh_current_vs_previous_year(month=mes, year=ano)
|
||||||
|
return jsonify({'reply': data})
|
||||||
|
|
||||||
|
if re.search(r"quantas faturas.*mês", user_input.lower()):
|
||||||
|
match = re.search(
|
||||||
|
r"(?:mês\s+de\s+([a-zç]+|\d{1,2}))(?:\s+do\s+ano\s+(\d{4}))?",
|
||||||
|
user_input.lower()
|
||||||
|
)
|
||||||
|
if match:
|
||||||
|
mes_input = match.group(1).strip().lower()
|
||||||
|
ano = int(match.group(2)) if match.group(2) else datetime.now().year
|
||||||
|
if mes_input.isdigit():
|
||||||
|
mes = int(mes_input)
|
||||||
|
else:
|
||||||
|
mes = month_map.get(mes_input)
|
||||||
|
if not mes:
|
||||||
|
return jsonify({'reply': "Mês não reconhecido. Tenta novamente."})
|
||||||
|
else:
|
||||||
|
mes = datetime.now().month
|
||||||
|
ano = datetime.now().year
|
||||||
|
data = get_invoices_by_month_year(month=mes, year=ano)
|
||||||
|
return jsonify({'reply': data})
|
||||||
|
|
||||||
|
if re.search(r"faturas.*instalações.*inativas", user_input.lower()):
|
||||||
|
data = get_invoices_from_inactive_units()
|
||||||
|
return jsonify({'reply': data})
|
||||||
|
|
||||||
|
if re.search(r"total de kwh.*tipo de edifícios", user_input.lower()):
|
||||||
|
match = re.search(r"tipo de edifícios\s+([a-zçãõáéíóúâêîôûäëïöü\s]+)", user_input.lower())
|
||||||
|
building_type = match.group(1).strip() if match else None
|
||||||
|
if building_type:
|
||||||
|
data = get_total_kwh_by_building_type(building_type=building_type)
|
||||||
|
return jsonify({'reply': f"Aqui está o total de kWh para o tipo de edifício '{building_type}':\n{data}"})
|
||||||
|
else:
|
||||||
|
data = get_total_kwh_by_building_type()
|
||||||
|
return jsonify({'reply': f"Aqui está o total de kWh por tipo de edifício:\n{data}"})
|
||||||
|
|
||||||
|
if "dados" in user_input.lower():
|
||||||
|
data = get_data()
|
||||||
|
return jsonify({'reply': f"\nDados do SQL Server:\n{data}"})
|
||||||
|
|
||||||
|
response = chat_with_gpt(user_input)
|
||||||
|
return jsonify({'reply': response})
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(port=3000, debug=True)
|
Loading…
x
Reference in New Issue
Block a user